就是给你长度为N的学列,有Q次查询,每次查询这写序列中能异或出来的第k小的值
本题是一个线性基的入门题。
其实线性基的求解过程就是一个高斯消元,它构建了一个二维的空间,N*bits这么大,
通过列与列相消,求解出基向量也就是空间的极大无关组,通过这几个元素能得到含盖空间中所有元素的无关组.
本题求的就是这个无关组能构建出来的第K小的值.
求这个值我们可以类比最理想情况下的无关组,
1 0 0 0 0 0 … 0 p1
0 1 0 0 0 0 … 0 p2
…
0 0 0 0 0 0 … 0 pn
那么对于第K小的值就是将K二进制展开,第i位上为1,就在结果上异或pn−i就好了
#include
#include
#include
#include
using namespace std;
int n,m;
unsigned long long a[10005],ins[100];
bool flag;
void EX_Ins(int n)
{
int i,j,k;
flag=0;
memset(ins,0,sizeof ins);
for(i=n;i;i--)
{
for(j=63;~j;j--)if((a[i]>>j)&1)
{
if(!ins[j])
{
ins[j]=a[i];
for(k=0;k<63;k++)
for(int r=k+1;r<=63;r++)
if((ins[r]>>k)&1)
ins[r]^=ins[k];
break;
}
else a[i]^=ins[j];
}
if(!a[i])flag=1;
}
return ;
}
int main()
{
//freopen("test.in","r",stdin);
int i,g,_g;
unsigned long long k;
for(scanf("%d",&_g),g=1;g<=_g;g++)
{
printf("Case #%d:\n",g);
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%llu",&a[i]);
//下面四行完成线性基的操作
EX_Ins(n);
for(m=i=0;i<=63;i++)
{
if(ins[i])ins[m++]=ins[i];
}
// for(i=0;i<=m-1;i++)
// cout<>m)puts("-1");//共能组成2的M次方个,如果k更大,那就impossible
else {
unsigned long long ret=0;
for(i=0;i>i)&1)
ret^=ins[i];
printf("%llu\n",ret);
}
}
}
return 0;
}