zoj 3591 Nim 博弈论

思路:先生成序列再求异或,最多的可能为n*(n+1)/2;

在去掉其中必败的序列,也就是a[i]=a[j]之间的序列。

代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<set>
 7 #include<vector>
 8 #define ll long long
 9 #define M 100005
10 #define inf 1e10
11 #define mod 1000000007
12 using namespace std;
13 int n,s,w,a[M];
14 int main()
15 {
16     int i,j,t;
17     scanf("%d",&t);
18     while(t--){
19         scanf("%d%d%d",&n,&s,&w);
20         int g=s;
21         a[0]=0;
22         for(i=1;i<=n;i++){
23             j=g;
24             if(j==0) j=g=w;
25             if(g%2==0) g=g/2;
26             else g=((g/2)^w);
27             a[i]=a[i-1]^j;
28         }
29         sort(a+1,a+n+1);
30         ll ans=(ll)(n+1)*n/2;
31         for(j=1,i=2;i<=n;i++){
32             if(a[i]==a[i-1]) j++;
33             else{
34                 if(a[i-1]==0) ans-=j;
35                 ans-=(ll)j*(j-1)/2;
36                 j=1;
37             }
38         }
39         ans-=(ll)j*(j-1)/2;
40         printf("%lld
",ans);
41     }
42     return 0;
43 }
View Code
原文地址:https://www.cnblogs.com/xin-hua/p/3339323.html