Solution:
线性基模板,求异或空间第k大(小)。
只讲一下需要注意的是:
求解线性基时,应按照从高往低位消元,这样才能保证基的单调性。
#include<string>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define RG register
#define IL inline
#define int long long
#define DB double
using namespace std;
IL int gi() {
char ch=getchar(); RG int x=0,w=0;
while(ch<'0'||ch>'9') {if (ch=='-') w=1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
return w?-x:x;
}
const int N=1e5+10;
int n,Q,cnt,ans,flag,a[N];
IL void Gauss_Jordan() {
RG int i,j,l;
cnt=0,flag=0;
// 此处i一定要从大到小枚举...
// 否则不能保证基的单调性...
for(i=63;i>=0;--i) {
for(j=cnt+1,l=0;j<=n;++j)
if((a[j]>>i)&1) {l=j;break;}
if(!l) continue;
swap(a[l],a[++cnt]);
for(j=1;j<=n;++j)
if(j!=cnt&&((a[j]>>i)&1)) a[j]^=a[cnt];
}
for(i=cnt+1;i<=n;++i)
if(!a[i]) {flag=1;break;}
}
signed main()
{
RG int i,j,x,T=gi(),Case=0;
while(T--) {
memset(a,0,sizeof(a));
for(i=1,n=gi();i<=n;++i) a[i]=gi();
Gauss_Jordan();
printf("Case #%lld:
",++Case);
for(Q=gi();Q;--Q) {
x=gi(),ans=0;
if(flag) --x;
if(x>(1ll<<cnt)-1) puts("-1");
else {
for(j=1;j<=cnt;++j)
if((x>>j-1)&1) ans^=a[cnt-j+1];
printf("%lld
",ans);
}
// 将x二进制分解...
}
}
return 0;
}