传统Nim:如果所有石子xor起来不为0,那么先手必胜,否则后手必胜
新Nim游戏:首先进行一个特殊的回合,先手和后手分别拿走若干堆石子(不能全部取完,可以不取),然后再进行Nim游戏
我们考虑先手能够获胜的条件为如果他能取走若干堆石子使得剩余的石子中不存在能够取出若干堆石子使得他异或为0,那么我们考虑线性基,发现先手必胜
先手取完若干堆石子之后只要剩余的石子是一组基,那么先手必胜,反之先手必败。
证明:一组基中不存在xor为0的情况,反之必然
由于题目还要求先手取出的数尽量小,那么我们贪心从大到小选出最大的线性基即可
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int D=30;
const int N=1000;
int n,x;
ll ans;
int b[D+10];
int a[N];
void put(int x){
int sum=x;
for (int i=D;i>=0;i--)
if ((x>>i)&1) {
if (b[i]) x^=b[i]; else {
b[i]=x; return ;
}
}
ans+=(ll)sum;
}
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++) {
scanf("%d",&a[i]);
}
sort(a+1,a+n+1);
for (int i=n;i>=1;i--) put(a[i]);
printf("%lld\n",ans);
}