一、题目
二、解法
首先考虑没有重复(序列个数等于线性基个数)的情况,那么问题就是求一个值的排名(跟求排名的值差不多)
如果有重复的情况呢?我们考虑一个值在线性基 位被异或为 ,那我们就把这个值归类到 位,设有 个多余的值。如果一个位置被选取了,那么选奇数个数的子集方案数 ,否则可以选当前位没有被选取,那么选偶数也是 ,总方案数就是 , 是重复的个数。
代码也就不难了,仿照求排名的值。
#include <cstdio>
#define int long long
const int jzm = 10086;
int read()
{
int x=0,flag=1;char c;
while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*flag;
}
int n,m,k,ans,p[40];
void ins(int x)
{
for(int i=30;i>=0;i--)
{
if(!(x>>i)) continue;
if(!p[i]) {p[i]=x;break;}
x^=p[i];
}
if(!x) m=m*2%jzm;
}
void work()
{
for(int i=1;i<=30;i++)
for(int j=0;j<i;j++)
if(p[i]&(1<<j))
p[i]^=p[j];
}
signed main()
{
n=read();m=1;
for(int i=1;i<=n;i++)
ins(read());
work();
k=read();
for(int i=0,t=1;i<=30;i++)
if(p[i])
{
if((k>>i)&1) ans+=t;
t<<=1;
}
printf("%lld\n",(ans*m+1)%jzm);
}