一个原来写的题。

既然最后是nim游戏,且玩家是先手,则希望第二回合结束后是一个异或和不为0的局面,这样才能必胜。

所以思考一下我们要在第一回合留下线性基

然后就是求线性基,因为要取走的最少,所以排一下序,从大到小求。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<cstdlib>
 8 #define ll long long
 9 using namespace std;
10 int read(){
11     int x=0,f=1;char ch=getchar();
12     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
13     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
14     return x*f;
15 }
16 bool cmp(int a,int b){return a>b;}
17 int n,a[105],b[35];
18 ll tot,ans;
19 int main(){
20     n=read();
21     for(int i=1;i<=n;i++)a[i]=read();
22     sort(a+1,a+1+n,cmp);
23     for(int i=1;i<=n;i++)tot+=1ll*a[i];
24     for(int i=1;i<=n;i++){
25         int t=a[i];
26         for(int j=30;j>=0;j--){
27             if(a[i]&(1<<(j-1))){
28                 if(!b[j]){b[j]=i;break;}
29                 else a[i]^=a[b[j]];
30             }
31         }
32         if(a[i])ans+=1ll*t;
33     }
34     printf("%lld\n",tot-ans);
35     return 0;
36 }
View Code

相关文章: