当年的我还是太naive啊。还以为是线性基sb题
对于先手的选择是非常重要的,我们必须控制对手无法把剩下的石子堆取出一部分使得异或和为0
意思就是取剩下的石子堆无法找到一个异或和为0的子集,判定方法即为线性基
除此之外还要去掉最少,而这又等于保留最多
考虑使用拟阵,子集限制即为异或和为0,遗传性显然,证明一下交换性:若|A|<|B|,在线性基中A的元素个数必定少于B,只要在B的基中随便找一个A不是1自己是1的位就行了
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; int a[110],lt[110];LL ans; bool cmp(int a1,int a2){return a1>a2;} bool insert(int d) { for(int i=30;i>=0;i--) if(d&(1<<i)) { if(lt[i]==0) {lt[i]=d;return true;} else d^=lt[i]; } return false; } int main() { int n,x; scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); sort(a+1,a+n+1,cmp); ans=0; for(int i=1;i<=n;i++) if(!insert(a[i]))ans+=(LL(a[i])); printf("%lld ",ans); return 0; }