hdu 3032 NIm or not Nim? Multi SG

题目大意:

可以选择在一堆石子中拿一些石子

或者把一堆石子划分成两个非空的石子堆

问先手必胜?


模板题

一个规律是\(n = 4m + k\)

\(sg(n) = n - 1(k = 0)\)

\(sg(n) = n(k = 1, k = 2)\)

\(sg(n) = n + 1(k = 3)\)


考虑证明:

对于\(\{1, 2, 3, 4, 5, 6, 7, 8\}\),都是成立的

考虑对于\(4n, 4n + 1, 4n + 2, 4n + 3\)四个归纳

首先,这四个数可以取\(1 \sim 4n - 1\)中所有数的\(sg\)

也就是除了\(1 \sim 4n\)中,除了\(4n - 1\)之外的所有数都会在后继状态的\(sg\)中出现

  • 对于\(sg(4n)\)

只需证明,不存在两个数,\(a + b = 4n\),并且\(sg(a) \oplus sg(b) = 4n - 1\)

\(a = 4k + 1\),那么\(sg(a) \oplus sg(b) = (4k + 1) \oplus (4n - 4k)\),这时\(a \oplus b\)的末两位为\(1\),不可能

\(a = 4k + 2\),那么\(sg(a) \oplus sg(b) = (4k + 2) \oplus (4n - 4k - 2)\),这时末两位为\(2 \oplus 2 = 0\),也不可能

\(a = 4k + 3\),那么\(sg(a) \oplus sg(b) = (4k + 4) \oplus (4n - 4k - 4)\),末两位为\(0\),不可能

\(a = 4k + 4\),那么\(sg(a) \oplus sg(b) = (4k + 3) \oplus (4n - 4k - 3)\),末两位为\(3 \oplus 1 = 2\),不可能

因此,\(sg(4n) = 4n - 1\)

  • 对于\(sg(4n + 1)\)

类似的归纳不存在两个数,\(a, b\),满足\(a + b = 4n + 1\),且\(sg(a) \oplus sg(b) = 4n + 1\)

  • 对于\(sg(4n + 2)\)\(sg(4n + 3)\)同理

只需要\(16\)次讨论即可


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define ll long long
#define ri register int
#define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
#define drep(io, ed, st) for(ri io = ed; io >= st; io --)

#define gc getchar
inline int read() {
    int p = 0, w = 1; char c = gc();
    while(c < '0' || c > '9') { if(c == '-') w = -1; c = gc(); }
    while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
    return p * w;
}

inline int get(int o) {
    int m = o & 3;
    if(m == 0) return o - 1;
    if(m == 1 || m == 2) return o;
    if(m == 3) return o + 1;
}

int main() {
    int T = read();
    while(T --) {
        int n = read(), sg = 0;
        rep(i, 1, n) sg ^= get(read());
        if(sg) printf("Alice\n");
        else printf("Bob\n");
    }
}

转载于:https://www.cnblogs.com/reverymoon/p/10151941.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值