BZOJ 4269: 再见Xor [高斯消元 线性基]
4269: 再见Xor
Description
给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值。
我太愚蠢了连数组开小了以及$2^{31}$爆$int$都不造
线性基裸题啊....
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <bitset> using namespace std; typedef long long ll; const int N=1e5+5,INF=1e9; inline int read(){ char c=getchar();int x=0; while(c<'0'||c>'9'){c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x; } int n,p; int a[N],bin[N]; void ini(){ bin[0]=1;for(int i=1;i<=30;i++) bin[i]=bin[i-1]<<1; } int now; void Gauss(int n){ now=1; for(int i=30;i>=0;i--){ int j=now; while(j<=n&&!(a[j]&bin[i])) j++; if(j==n+1) continue; if(j!=now) swap(a[j],a[now]); for(int k=1;k<=n;k++) if(k!=now&&(a[k]&bin[i])) a[k]^=a[now]; now++; } now--; } int main(){ freopen("in","r",stdin); n=read(); for(int i=1;i<=n;i++){ int x=read(); while(x==0&&i<n) x=read(),i++; if(x!=0) a[++p]=x; } ini(); Gauss(p); int mx=0; for(int i=1;i<=now;i++) mx^=a[i]; printf("%d %d\n",mx,mx^a[now]); }
Copyright:http://www.cnblogs.com/candy99/