才想起来线性基还没学过呢
其实我并没有怎么搞懂线性基到底咋用而且这个求法也是奥妙重重
我们每次考虑向当前已有的基中插入一个数
显然基是之前的数异或的结果
所以从高位到低位判断,如果这一位已经有基了,那么我们把这个数与基异或一下,这个数的这一位就Biu地不见了
否则我们就把这个数(已经被异或得不成人形了)插到这一位上去
同时线性基要满足一些性质才好用,比如说每个基最简化,于是我们还要refresh一下已经形成的基
(以上都是我口胡的大家不要信)
然后对于询问什么的二进制拆分一下(其实我也不知道怎么搞,我抄的代码)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
ll base[70];
bool ins_base(ll x){
for(int i=63;i>=0;i--)
if(x>>i&1){
if(!base[i]){
base[i]=x;
for(int j=0;j<=63;j++)
for(int k=j+1;k<=63;k++)
if(base[k]>>j&1)base[k]^=base[j];
return true;
}else x^=base[i];
}
if(!x)return false;
else return true;
}
int main(){
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
int T;scanf("%d",&T);
for(int kase=1;kase<=T;kase++){
printf("Case #%d:\n",kase);
memset(base,0,sizeof(base));
int n;ll x;bool flag=false;
scanf("%d",&n);
while(n--){
scanf("%lld",&x);
if(!ins_base(x))flag=true;
}
int cnt=0;
for(int i=0;i<=63;i++)
if(base[i])base[cnt++]=base[i];
int q;scanf("%d",&q);
while(q--){
scanf("%lld",&x);
x-=flag;
if(x>>cnt)puts("-1");
else{
ll ans=0;
for(int i=0;i<cnt;i++)
if(x>>i&1)ans^=base[i];
printf("%lld\n",ans);
}
}
}
return 0;
}