题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3105
题意是要取一些数使得剩余的数xor和的子集不为0
拟阵。求解极大线性无关组。贪心从大到小放,开31个向量表示二进制第i位数的情况,如果一个数能被之前的数表示,那么这个数不用取。注意long long。
#include<cstring> #include<iostream> #include<algorithm> #include<cstdio> #define maxn 109 #define rep(i,l,r) for (int i=l;i<=r;i++) #define down(i,l,r) for (int i=l;i>=r;i--) #define clr(x,y) memset(x,y,sizeof(x)) #define ll long long using namespace std; int n,m=31; ll ans,sum,a[maxn],w[maxn],bin[maxn]; int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); } while (isdigit(ch)){ x=x*10+ch-'0'; ch=getchar(); } return x*f; } bool cmp(int x,int y){ return x>y; } int main(){ n=read(); rep(i,1,n) a[i]=read(),sum+=a[i]; rep(i,1,m) bin[i]=1<<(i-1); sort(a+1,a+1+n,cmp); rep(i,1,n){ int now=a[i]; down(j,m,1) if (a[i]&bin[j]) { if (w[j]) a[i]^=a[w[j]]; else { w[j]=i; break; } } if (a[i]) ans+=now; } if (ans!=0) printf("%lld ",sum-ans); else puts("-1"); return 0; }