题意:给出一组数组,可以任意选取子集并异或,求第 k 小异或值
分析:线性基裸体
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
struct L_B{
long long d[61],p[61];
int cnt;
L_B()
{
memset(d,0,sizeof(d));
memset(p,0,sizeof(p));
cnt=0;
}
bool insert(long long val)
{
for (int i=60;i>=0;i--)
if (val&(1LL<<i))
{
if (!d[i])
{
d[i]=val;
break;
}
val^=d[i];
}
return val>0;
}
void rebuild()
{
for (int i=60;i>=0;i--)
for (int j=i-1;j>=0;j--)
if (d[i]&(1LL<<j))
d[i]^=d[j];
for (int i=0;i<=60;i++)
if (d[i])
p[cnt++]=d[i];
}
long long kthquery(long long k)
{
int ret=0;
if (k>=(1LL<<cnt))
return -1;
for (int i=60;i>=0;i--)
if (k&(1LL<<i))
ret^=p[i];
return ret;
}
};
int main()
{
int T,n,q;
scanf("%d",&T);
for(int cas=1;cas<=T;cas++)
{
L_B xxj=L_B();
scanf("%d",&n);
for(int i=0;i<n;i++)
{
long long k;
scanf("%lld",&k);
xxj.insert(k);
}
scanf("%d",&q);
printf("Case #%d:\n",cas);
xxj.rebuild();
while(q--)
{
long long k;
scanf("%lld",&k);
if(n!=xxj.cnt) k--;
long long ans=xxj.kthquery(k);
printf("%lld\n",ans);
}
}
}