bzoj3105 [cqoi2013]新Nim游戏
很明显,题目要你求在拿走最少的火柴棍的情况下,如何让剩下的火柴堆的亦或值不含0。
先贪心的拍一发序,在动态的维护一下线性基就可以了。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; inline int cmp(int a,int b){ return a>b; } inline int read(){ int x=0,f=1,ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-'){f=-1;}ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,a[105]; int b[105]; inline bool ok(int x){ int i; for(i=30;i>=0;i--) if(b[i]&&((x>>i)&1)) x^=b[i]; if(x) return true; return false; } inline void add(int x){ int i; for(i=30;i>=0;i--) if(!b[i]&&((x>>i)&1)){ b[i]=x; return ; } else if(b[i]&&((x>>i)&1)) x^=b[i]; } int main(){ n=read();int i; long long ans=0; for(i=1;i<=n;i++) a[i]=read(); sort(a+1,a+1+n,cmp); for(i=1;i<=n;i++) if(ok(a[i])) add(a[i]); else ans+=a[i]; cout<<ans<<endl; return 0; }