不知道线性基是什么东西的可以看看蒟蒻的
题目大意:求一堆数字能异或出的第$k$大的数是多少
线性基求第k大好珂怕……
据大佬们说就是把$k$给二进制拆分,如果$k$的第$i$位为1,那么$ans^=b[i]$
然后就是注意矩阵得消成对角矩阵而不是上三角矩阵……
这样的话$1$只会出现在对角线上
记$cnt$为对角线上有多少个$1$
显然能获得的异或值总共有$1<<cnt$个(包括0)
然后注意,如果$cnt!=n$,那么这一堆数字就是线性相关的,可以异或出0
否则的话说明这一堆数字线性无关,无法异或出0,那么得把$k++$(因为我们这里的$k$是默认能取到0的)
然后剩下的细节看代码好了
1 //minamoto 2 #include3 #include 4 #include 5 #define ll long long 6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 7 char buf[1<<21],*p1=buf,*p2=buf; 8 inline ll read(){ 9 #define num ch-'0'10 char ch;bool flag=0;ll res;11 while(!isdigit(ch=getc()))12 (ch=='-')&&(flag=true);13 for(res=num;isdigit(ch=getc());res=res*10+num);14 (flag)&&(res=-res);15 #undef num16 return res;17 }18 const int N=1e5+5;19 int n,m,k;ll a[N],b[105];20 void init(){21 for(int i=1;i<=n;++i)22 for(int j=63;j>=0;--j){23 if(a[i]>>j&1){24 if(b[j]) a[i]^=b[j];25 else{26 b[j]=a[i];27 for(int k=j-1;k>=0;--k)28 if(b[k]&&(b[j]>>k&1)) b[j]^=b[k];29 for(int k=j+1;k<=63;++k)30 if(b[k]>>j&1) b[k]^=b[j];31 break;32 }33 }34 }35 }36 int main(){37 // freopen("testdata.in","r",stdin);38 int T=read();39 for(int cas=1;cas<=T;++cas){40 memset(b,0,sizeof(b));n=read();41 for(int i=1;i<=n;++i) a[i]=read();42 init();43 int cnt=0;44 for(int i=0;i<=63;++i)45 if(b[i]) ++cnt;46 m=read();47 printf("Case #%d:\n",cas);48 while(m--){49 ll x=read();50 if(cnt==n) ++x;51 if(x>(1ll< =0;--i){55 if(b[i]){56 ll now=(1ll<<(tmp-1));57 if(x>now) x-=now,ans^=b[i];58 --tmp;59 }60 }61 printf("%lld\n",ans);62 }63 }64 return 0;65 }