解析
关键结论:
若 nnn 个数组成的线性基大小为 SSS,则其子集异或组成的结果有 2S2^S2S 种,且每种结果都有 2n−S2^{n-S}2n−S 种方案。
证明:考虑 n−Sn-Sn−S 个没有加入线性基的元素的任意一个子集,其异或和为 xxx,线性基中的互不相同的 2S2^S2S 种异或和分别与 xxx 异或,必然得到 2S2^S2S 种不同结果,又由于这 nnn 个数异或的结果只有 2S2^S2S 个,所以就是每种结果的方案+1。一共有 2n−S2^{n-S}2n−S 个 xxx,每种结果也就有 2n−S2^{n-S}2n−S 个方案。
有了这个结论本题也就结束了,直接求出排名后乘一个2的幂次即可。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define int ll
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define OK debug("OK\n")
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
const int N=4e5+100;
const int mod=1e9+7;
int n,m,d;ll a[70],mi[70],o=30,num;
inline int ins(int x){for(int i=o;i>=0;i--){if(!(x&mi[i])) continue;if(!a[i]){a[i]=x;return true;}x^=a[i];}return false;
}
int rnk(int x){int res(0),now=num;for(int i=o;i>=0;i--){if(!a[i]) continue;now--;if(x&mi[i]){//x^=a[i];res+=mi[now];}}return res;
}signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifmi[0]=1;for(int i=1;i<=o;i++) mi[i]=mi[i-1]<<1;n=read();for(int i=1;i<=n;i++) num+=ins(read());//for(int i=0;i<=o;i++) if(a[i]) printf("%lld ",a[i]);//puts("");int ans=rnk(read());for(int i=1;i<=n-num;i++) ans=ans*2%10086;printf("%lld\n",(ans+1)%10086);
}
/*
*/