LOJ114 k大(xiao)异或和(线性基)
构造线性基后将其消至对任意位至多只有一个元素该位为1。于是就可以贪心了,将k拆成二进制就好。注意check一下是否能异或出0。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define N 100010 #define ll long long ll read() { ll x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } bool flag=0; ll n,m,base[51],s; int main() { freopen("kxor.in","r",stdin); freopen("kxor.out","w",stdout); n=read(); for (int i=1;i<=n;i++) { ll x=read(); for (int j=50;~j;j--) if (x&(1ll<<j)) if (!base[j]) {base[j]=x;break;} else x^=base[j]; if (!x) flag=1; } for (int i=50;~i;i--) if (base[i]) { s++; for (int j=i-1;~j;j--) if (base[i]&(1ll<<j)) base[i]^=base[j]; } s=1ll<<s; m=read(); for (int i=1;i<=m;i++) { ll k=read()-flag; if (k>=s) printf("-1\n"); else { ll ans=0; for (int j=0;j<=50;j++) if (base[j]) { ans^=(k&1)*base[j]; k>>=1; } printf("%lld\n",ans); } } fclose(stdin);fclose(stdout); return 0; }