题目大意:给定一个 n 个数的集合 S 和一个数 x ,求 x 在 S 的 2n 个子集从小到大的异或和序列中最早出现的位置
题解:考虑一个结论:对于一个n个数构成的大小为 k 的线性基
可以得到的
2k
个异或和每个会重复
2n−k
次
从高到低枚举二进制位,异或这一位后小于 k 就加上
我的收获:2333
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bitset>
using namespace std;
typedef long long ll;
const int N=1e5+5,INF=1e9,P=10086;
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
int n,x;
int a[N],bin[70];
void ini(){
bin[0]=1;for(int i=1;i<=30;i++) bin[i]=bin[i-1]<<1;
}
int now;
void Gauss(){
now=1;
for(int i=30;i>=0;i--){
int j=now;
while(j<=n&&!(a[j]&bin[i])) j++;
if(j==n+1) continue;
if(j!=now) swap(a[j],a[now]);
for(int k=1;k<=n;k++)
if(k!=now&&(a[k]&bin[i])) a[k]^=a[now];
now++;
}
now--;
}
int main(){
freopen("in","r",stdin);
ini();
n=read();
for(int i=1;i<=n;i++) a[i]=read();
Gauss();
x=read();
int val=0,sum=0;
for(int i=1;i<=now;i++) if((val^a[i])<=x){
val^=a[i];
sum=(sum+(1<<(now-i))%P)%P;
}
for(int i=1;i<=n-now;i++) sum=(sum<<1)%P;
printf("%d",(sum+1)%P);
}