Gym 101147.A

来源:互联网 发布:搜索引擎优化教程 编辑:程序博客网 时间:2024/06/04 18:27

题意:m堆石子,每堆有对应一个(BiNi),表示这堆有Ni个石子,每次可以拿Bix个石子(1BxiNi),谁不能拿谁输,1和2轮流拿,两人足够机智,问谁必胜。

思路:首先分奇偶性讨论,显然在Bi为奇数的时候,我们容易得到,Ni为奇数和偶数时候,分别是先手必胜、后手必胜。sg分别是1和0。

  然后是Bi为偶数的时候,我们可以对Bi^x进行一个二项式展开,有两种展开,(B - 1 + 1),(B + 1 - 1),我们选择后者进行展开,那么,由于是(a-b)^x,奇偶性影响每一项的符号,会得到两种展开,B^x = K*(B+1) + 1 或B^x =K*(B+1) + B。

  令Ni=y*(B+1)+T(0<=T<=B),那么问题变成T个石子,每次可以拿1个或B个。由于T<=B,所以只有当T=B时先手有机会第一次拿B个,其他所有情况两个人都无法拿B个,当T < B时,T为奇则先手胜(sg=1),T为偶则后手胜(sg=0),T=B时两个后继状态分别是B-1和0。B-1考虑一下奇偶性就能知道sg值,然后是0的sg值。
  

#include <bits/stdc++.h>using namespace std;int main(){    freopen("powers.in", "r", stdin);    int T;    scanf("%d", &T);    while(T--)    {        int G;        scanf("%d", &G);        int ans = 0;        for(int i = 0; i < G; i++)        {            int b, n;            scanf("%d%d", &b, &n);            if(b & 1)            {                if(n & 1)   ans ^= 1;                else ans ^= 0;            }            else            {                int mod = n % (b + 1);                if(mod == b)                {                    if(b & 1)   ans  ^= 1;                    else ans ^= 2;                }                else                {                    if(mod & 1) ans ^= 1;                    else ans ^= 0;                }            }        }        printf("%d\n", ans == 0 ? 2 : 1);    }    return 0;}