1. 程式人生 > >bzoj3105: [cqoi2013]新Nim遊戲

bzoj3105: [cqoi2013]新Nim遊戲

當年的我還是太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\n",ans); return 0; }