zoukankan      html  css  js  c++  java
  • zoj3591 Nim(Nim博弈)

    ZOJ 3591 Nim(Nim博弈)

    题目意思是说有n堆石子,Alice只能从中选出连续的几堆来玩Nim博弈,现在问Alice想要获胜有多少种方法(即有多少种选择方式)。

    方法是这样的,由于Nim博弈必胜的条件是所有数的抑或值不为0,证明见  点击  ,所以答案就转化为原序列有多少个区间的亦或值为0,用n*(n+1) / 2 减去这个值就可以了。

    而求有多少个区间的亦或值为0,实际上就是求对于亦或值的前缀nim[i],满足nim[i] == nim[j] 的对数,这时只要对nim数组排序就可以算了

    详见代码:

     1 #include <map>
     2 #include <set>
     3 #include <stack>
     4 #include <queue>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <vector>
     8 #include <cstdio>
     9 #include <cctype>
    10 #include <cstring>
    11 #include <cstdlib>
    12 #include <iostream>
    13 #include <algorithm>
    14 using namespace std;
    15 #define INF 0x3f3f3f3f
    16 #define inf (-((LL)1<<40))
    17 #define lson k<<1, L, mid
    18 #define rson k<<1|1, mid+1, R
    19 #define mem0(a) memset(a,0,sizeof(a))
    20 #define mem1(a) memset(a,-1,sizeof(a))
    21 #define mem(a, b) memset(a, b, sizeof(a))
    22 #define FIN freopen("in.txt", "r", stdin)
    23 #define FOUT freopen("out.txt", "w", stdout)
    24 #define rep(i, a, b) for(int i = a; i <= b; i ++)
    25 
    26 template<class T> T CMP_MIN(T a, T b) { return a < b; }
    27 template<class T> T CMP_MAX(T a, T b) { return a > b; }
    28 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
    29 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
    30 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
    31 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
    32 
    33 //typedef __int64 LL;
    34 typedef long long LL;
    35 const int MAXN = 110000;
    36 const int MAXM = 20010;
    37 const double eps = 1e-4;
    38 //LL MOD = 987654321;
    39 
    40 int n, a[MAXN], x, s, w, T;
    41 
    42 int main()
    43 {
    44     while(~scanf("%d", &T)) while(T--) {
    45         cin >> n >> s >> w;
    46         LL ans = (LL)n * (n + 1) / 2;
    47         int g = s;
    48         rep (i, 1, n) {
    49             x = g;
    50             if( x == 0 )    { x = g = w; }
    51             if( g%2 == 0 )  { g = (g/2); }
    52             else            { g = (g/2) ^ w; }
    53             a[i] = a[i - 1] ^ x;
    54             if(a[i] == 0) ans --;
    55         }
    56         sort(a + 1, a + n + 1);
    57         int num = 1;
    58         rep (i, 2, n) {
    59             if(a[i] == a[i - 1]) {
    60                 ans -= num;
    61                 num++;
    62             }
    63             else num = 1;
    64         }
    65         cout << ans << endl;
    66     }
    67     return 0;
    68 }
  • 相关阅读:
    使用CustomValidate自定义验证控件
    C#中金额的大小写转换
    Andriod出错之Unable to build: the file dx.jar was not loaded from the SDK folder!
    VC 编写的打字练习
    机房工作笔记Ping只有单向通
    web服务协同学习笔记(1)
    Dll 学习3 将MDI子窗口封装在DLL中
    机房工作学习文件共享
    Andriod出错之Failed to find an AVD compatible with target 'Android 2.2'
    Andriod出错之wrapper was not properly loaded first
  • 原文地址:https://www.cnblogs.com/gj-Acit/p/4492722.html
Copyright © 2011-2022 走看看