@xzyxzy
2018-04-06T08:31:00.000000Z
字数 2577
阅读 1681
数学
网上优秀博客:https://blog.sengxian.com/algorithms/linear-basis
机房大佬们的总结 yyb%yl%zsy orz
所谓基大概就是指
在一个集合内定义一种运算,用基中的元素可以运算出所有用集合中的元素运算的结果
可以理解成基是一个集合的。。浓缩?
然后线性基呢就是这个运算是异或运算
线性基中以每一位为最高位的1的数至多只有一个
所以把一个元素加入线性基中,那么
if(x&(1<<j)){if(!p[j]){p[j]=x;break;}//一定要break!!else x^=p[j];}
一个技巧
最大异或和(较简单【模板】线性基)
#include<iostream>#include<cstdio>#include<cstdlib>#define ll long longusing namespace std;ll read(){char ch=getchar();ll h=0,t=1;while(ch!='-'&&(ch>'9'||ch<'0'))ch=getchar();if(ch=='-')t=-1,ch=getchar();while(ch>='0'&&ch<='9'){h=h*10+ch-'0';ch=getchar();}return h*t;}ll N,A[70],ans;int main(){N=read();for(int i=1;i<=N;i++){ll x=read();for(int j=63;j>=0;j--)if(x&(1LL<<j)){if(!A[j]){A[j]=x;break;}else x^=A[j];}}for(int i=63;i>=0;i--)if((ans^A[i])>ans)ans^=A[i];printf("%lld\n",ans);return 0;}
K小异或和(比较难以理解,纠结了一个晚上,想通了[HDU2949] XOR)
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#define ll long longusing namespace std;ll read(){char ch=getchar();ll h=0,t=1;while(ch!='-'&&(ch>'9'||ch<'0'))ch=getchar();if(ch=='-')t=-1,ch=getchar();while(ch>='0'&&ch<='9'){h=h*10+ch-'0';ch=getchar();}return h*t;}ll T,p[100],Q[100],cnt,N,M,CC=0;void Insert(ll x){for(ll i=63;i>=0;i--){if(!(x>>i))continue;if(!p[i]){p[i]=x;return;}else x^=p[i];}CC=1;//表示线性基可以异或出0}void Rebuild(){for(ll i=63;i>=0;i--)for(ll j=i-1;j>=0;j--)if(p[i]&(1LL<<j))p[i]^=p[j];/*重建线性基,使得p[i]某非最高位上有1当且仅当p[该位]=0使得能够保证异或上p[i]一定会使答案增大*/for(ll i=0;i<=63;i++)if(p[i])Q[cnt++]=p[i];}void Query(ll k){if(k>=(1LL<<cnt)){puts("-1");return;}//超过所有能够异或出来的结果个数 (线性基中cnt个元素选或者不选)ll res=0;for(ll i=cnt-1;i>=0;i--)if(k&(1LL<<i))res^=Q[i];/*在线性基Q[0]~Q[cnt-1]中,从小到大是Q[0],Q[1],Q[1]^Q[0],Q[2],Q[2]^Q[0],Q[2]^Q[1],Q[2]^Q[0]^Q[1].....所以第k大的组成元素就是所有k的二进制位上的数的异或和*/printf("%lld\n",res);}int main(){T=read();for(ll w=1;w<=T;w++){N=read();cnt=0;CC=0;memset(p,0,sizeof(p));memset(Q,0,sizeof(Q));for(ll i=1;i<=N;i++)Insert(read());Rebuild();M=read();printf("Case #%lld:\n",w);for(ll i=1;i<=M;i++){ll k=read()-CC;//查询第k小异或和if(!k)puts("0");else Query(k);}}return 0;}