一、題目
二、解法
首先考慮沒有重複(序列個數等於線性基個數)的情況,那麼問題就是求一個值的排名(跟求排名的值差不多)
如果有重複的情況呢?我們考慮一個值在線性基位被異或爲,那我們就把這個值歸類到位,設有個多餘的值。如果一個位置被選取了,那麼選奇數個數的子集方案數,否則可以選當前位沒有被選取,那麼選偶數也是,總方案數就是,是重複的個數。
代碼也就不難了,仿照求排名的值。
#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);
}