2018.12.07【LOJ114】k 大異或和(線性基)(高斯消元)
阿新 • • 發佈:2018-12-17
傳送門
解析:
先求一個線性基,然後高斯消元解線性空間,然後基本上就是亂搞把第 大湊出來就行了。
程式碼:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc get_char
#define pc put_char
#define cs const
namespace IO{
cs int Rlen=1<<18|1;
char buf[Rlen],*p1,*p2;
char obuf[Rlen],*p3=obuf,*p4=obuf+Rlen;
inline char get_char(){
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
inline ll getint(){
re ll num;
re char c;
while(!isdigit (c=gc()));num=c^48;
while(isdigit(c=gc()))num=num*10+(c^48);
return num;
}
inline void put_char(cs char &c){
*p3++=c;
if(p3==p4)fwrite(obuf,1,Rlen,stdout),p3=obuf;
}
inline void outint(ll a){
static char ch[23];
if(a==0)pc('0');
if(a<0)pc('-'),a=-a;
while(a)ch[++ch[0]]=a-a/10 *10,a/=10;
while(ch[0])pc(ch[ch[0]--]^48);
}
inline void FLUSH(){
if(p3==obuf)return ;
fwrite(obuf,1,p3-obuf,stdout);
p3=obuf;
}
}
using namespace IO;
int n,m;
ll b[51];
ll num[51],cnt;
int main(){
n=getint();
for(int re i=1;i<=n;++i){
re ll u=getint();
for(int re i=50;~i;--i)
if(u&(1ll<<i)){
if(!b[i]){
b[i]=u;
break;
}
else u^=b[i];
}
}
for(int re i=1;i<=50;++i)
for(int re j=0;j<i;++j){
if((1ll<<j)&b[i])
b[i]^=b[j];
}
for(int re i=0;i<=50;++i)
if(b[i])num[cnt++]=b[i];
m=getint();
while(m--){
re ll k=getint();
if(cnt!=n)--k;
if(k>=(1ll<<cnt)){
outint(-1);pc('\n');
continue;
}
re ll res=0;
for(int re i=0;i<=50;++i){
if(k&(1ll<<i))
res^=num[i];
}
outint(res);
pc('\n');
}
FLUSH();
return 0;
}