看了半天题,没想出怎么用高斯消元解题,看完别人ac明白。
首先,用二进制去看待每一个数,因为xor其实就是二进制的不进位加法。
比如 (十进制)2^0 2^1
1 1
2 1
3 1 1
其实3参与的xor可以用(1^2)代替,因为1 , 2 ,3线性相关。
所以需要做的就是求出这n个数的线性无关基,这是就是可以用高斯消元,但是要求的是第几小 ,所以希望每个消元后的数都尽量小,所以应该从高位开始消元
不理解可以看一下下边的数据(同样n个数不同姿势出来的结果)
//从高位消元
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0
0
1
2
4
8
16
32
64
128
256
512
3072
9216
20480
66560
561152
//从低位开始消元
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0
0
1
2
4
8
16
32
64
128
256
512
66560
67584
73728
561152
573440
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <stack>
#include <vector>
#include <string.h>
#include <queue>
#define msc(X) memset(X,-1,sizeof(X))
#define ms(X) memset(X,0,sizeof(X))
typedef long long LL;
using namespace std;
LL a[10005];
int n;
//求第几小应该从最高位开始消元,这样保证了线性无关组元素和最小
void Guass(void)
{
int max_r,col,k;
for(k=0,col=60;k<n&&col>=0;col--)
{
max_r=k;
for(int i=k+1;i<n;i++)
if(a[i]&(1ll<<col)) {
max_r=i;
break;
}
if((a[max_r]&(1ll<<col))==0)
continue;
if(max_r!=k)
swap(a[k],a[max_r]);
for(int i=0;i<n;i++)
if(i!=k&&(a[i]&(1ll<<col)))
a[i]^=a[k];
k++;
}
sort(a,a+n);
n=unique(a,a+n)-a;
}
LL cal(LL k)
{
LL ans=0;
int i=0;
if(a[0]==0){
if(k==1) return 0;
k--;
i++;
}
for(;i<n&&k;k>>=1,i++)
if(k&1)
ans^=a[i];
if(i==n&&k) return -1;
return ans;
}
int main(int argc, char const *argv[])
{
int t,ti=0;
scanf("%d",&t);
while(++ti<=t){
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%I64d",a+i);
Guass();
printf("Case #%d:\n",ti);
int q;
scanf("%d",&q);
while(q--){
LL k;
scanf("%I64d",&k);
printf("%I64d\n",cal(k) );
}
}
return 0;
}