Nim游戏的结论为,当目前所有数字异或和不为零是先手必胜,必胜策略为使得操作后的异或和为0。
所以如果在这个题目下后手想赢,就要拿完后使异或和为0,所以先手就要使后手无法做到这个操作,也就是说使第一轮拿完后,任意几堆火柴数量的异或和都不为零。用贪心的思想,把数从大到小排序。对于一个数,如果能插入线性基则插入,不能则添加到答案中。对于一个位置,先用大数占上而拿走之后的小数,最后答案就会比较小。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=110;
namespace io{
const int SIZE=(1<<21)+1;
char ibuf[SIZE],*iS,*iT,obuf[SIZE],*oS=obuf,*oT=oS+SIZE-1,c,qu[55];int qr;
#define gc() (iT==iS?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),iT==iS?EOF:*iS++):*iS++)
inline void flush(){
fwrite(obuf,1,oS-obuf,stdout);
oS=obuf;
}
inline void putc(char x){
*oS++ =x;
if(oS==oT)flush();
}
template <class I>
inline void gi(I &x){
for(c=gc();c<'0'||c>'9';c=gc());
for(x=0;c>='0'&&c<='9';c=gc())x=x*10+(c&15);
}
template <class I>
inline void print(I &x){
if(!x)putc('0');
while(x)qu[++qr]=x%10+'0',x/=10;
while(qr)putc(qu[qr--]);
}
}
using io::gi;
using io::putc;
using io::print;
int n,a1[N],b1[35];
long long ans=0;
bool cmp(int a,int b){
return a>b;
}
int main(){
gi(n);
for(int i=1;i<=n;++i)gi(a1[i]);
sort(a1+1,a1+n+1,cmp);
memset(b1,0,sizeof b1);
for(int tmp,i=1;i<=n;++i){
tmp=a1[i];
for(int j=30;j>=0;--j){
if(tmp&(1<<j)){
if(!b1[j]){b1[j]=tmp;break;}
tmp^=b1[j];
}
}
if(!tmp)ans+=1ll*a1[i];
}
print(ans);
io::flush();
return 0;
}