HDU 3949 XOR

来源:互联网 发布:date js 编辑:程序博客网 时间:2024/06/05 20:50

才想起来线性基还没学过呢

其实我并没有怎么搞懂线性基到底咋用而且这个求法也是奥妙重重

我们每次考虑向当前已有的基中插入一个数

显然基是之前的数异或的结果

所以从高位到低位判断,如果这一位已经有基了,那么我们把这个数与基异或一下,这个数的这一位就Biu地不见了

否则我们就把这个数(已经被异或得不成人形了)插到这一位上去

同时线性基要满足一些性质才好用,比如说每个基最简化,于是我们还要refresh一下已经形成的基

以上都是我口胡的大家不要信

然后对于询问什么的二进制拆分一下(其实我也不知道怎么搞,我抄的代码

#include<iostream>#include<cstdio>#include<cstring>using namespace std;typedef long long ll;ll base[70];bool ins_base(ll x){for(int i=63;i>=0;i--)if(x>>i&1){if(!base[i]){base[i]=x;for(int j=0;j<=63;j++)for(int k=j+1;k<=63;k++)if(base[k]>>j&1)base[k]^=base[j];return true;}else x^=base[i];}if(!x)return false;else return true;}int main(){//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);int T;scanf("%d",&T);for(int kase=1;kase<=T;kase++){printf("Case #%d:\n",kase);memset(base,0,sizeof(base));int n;ll x;bool flag=false;scanf("%d",&n);while(n--){scanf("%lld",&x);if(!ins_base(x))flag=true;}int cnt=0;for(int i=0;i<=63;i++)if(base[i])base[cnt++]=base[i];int q;scanf("%d",&q);while(q--){scanf("%lld",&x);x-=flag;if(x>>cnt)puts("-1");else{ll ans=0;for(int i=0;i<cnt;i++)if(x>>i&1)ans^=base[i];printf("%lld\n",ans);}}}return 0;}


0 0
原创粉丝点击