HDU-3949 XOR
阿新 • • 發佈:2019-02-19
思路:先求出a[]的線性基f[],然後將線性基的每一位進行消除使其只有本身的那一位,在將f[i]中非0的全部移動f[1,m]中,m為非0的個數,這樣對於第K個數,就是將K轉為二進位制中為1的f[]異或起來即可。另外還要處理有0的情況,這時需要將K-=1
Code :
#include<iostream> #include<cstring> #include<cstdio> using namespace std; typedef long long LL; int n,m,Q,T; int pp; LL f[65]; void Insert(LL x); void Build(); LL Query(LL k); int main() { scanf("%d",&T); for(int t=1;t<=T;++t) { memset(f,0,sizeof(f)); pp=m=0; scanf("%d",&n); LL x; for(int i=0;i<n;++i) { scanf("%lld",&x); Insert(x); } Build(); printf("Case #%d:\n",t); scanf("%d",&Q); while(Q--){ scanf("%lld",&x); x-=pp; if(x>=((LL)1<<m)) printf("-1\n"); else printf("%lld\n",Query(x)); } } return 0; } void Insert(LL x) { for(int i=63;i>=0;--i) if(x>>i){ if(!f[i]){ f[i]=x; break; } x^=f[i]; } if(!x) pp=1; } void Build() { for(int i=0;i<=63;++i) for(int j=i+1;j<=63;++j) if((f[j]>>i)&1) f[j]^=f[i]; for(int i=0;i<=63;++i) if(f[i]) f[m++]=f[i]; } LL Query(LL k) { int i=0; LL res=0; while(k){ if(k&1) res=res^f[i]; k>>=1; ++i; } return res; }