题解:P11713 [清华集训 2014] 玛里苟斯
线性代数好题。
首先,第一步观察就是你可以直接将
于是我们要求的就是线性基中所有能被表示出来的
直接暴力枚举选择哪
于是我们先枚举这
为了包含这
还有一个问题就是精度不会爆掉吗?可以发现唯一出现小数的地方是
时间复杂度为
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int maxn=70;
struct BASE{
int lim; ull c[maxn];
void init(int z){ lim=z; for(int i=0;i<=z;i++) c[i]=0; }
bool insert(ull v){
for(int i=lim;i>=0;i--){
if(!(v&(1ull<<i))) continue;
if(!c[i]){ c[i]=v; return 1; }
v^=c[i];
}
return 0;
}
bool chk(ull v){
for(int i=lim;i>=0;i--)
if(v&(1ll<<i)) v^=c[i];
return (!v);
}
}b,b2;
int n,m,k,d[maxn],e[maxn]; ull ans=0;
void dfs(int x){
if(x==k+1){
int res=1; b2.init(k-1);
for(int i=1;i<=k;i++) res+=e[i];
for(int i=0;i<=m;i++){
if(!b.c[i]) continue;
int z=d[i],x=0;
for(int j=1;j<=k;j++)
if(b.c[i]&(1ull<<e[j])) x|=(1<<j-1);
if(b2.insert(x)) res--;
}
if(b2.chk((1<<k)-1)) ans+=(1ull<<res); return ;
}
for(int i=0;i<=m;i++) e[x]=i,dfs(x+1);
}
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin>>n>>k; b.init(63);
for(int i=1;i<=n;i++){
ull v; cin>>v;
b.insert(v);
}
m=63; while(!b.c[m]) m--; dfs(1);
if(ans%2==0) cout<<ans/2;
else cout<<ans/2<<".5";
return 0;
}