[HDU 2509] Be the Winner (博弈、分裂游戏)

本质上是一个 Anti-Nim Game。考虑如何计算 SG 函数。

如果当前有堆\(x\)个石子,我取出任意个后,一定会把当前堆分为左右两堆,我们可以枚举左右两堆的大小\(l,r\) ,保证\(0\le l + r < x\),则有

\[SG(x) = \mathrm{mex} ( SG(l)\oplus SG(r)) \]

#include <bits/stdc++.h>

using namespace std;

const int inf = INT_MAX / 2;

using vi = vector<int>;

vi g(101, -1);

int mex(vi p) {
    if (p.empty()) return 0;
    ranges::sort(p);
    p.resize(unique(p.begin(), p.end()) - p.begin());
    for (int i = 0; i < p.size(); i++)
        if (i != p[i]) return i;
    return p.size();
}


int sg(int x) {
    if (g[x] != -1) return g[x];
    vi p;
    for (int l = 0; l < x; l++)
        for (int r = 0; l + r < x; r++)
            p.push_back(sg(l) ^ sg(r));
    return g[x] = mex(p);
}

int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;

    int res = 0, f = 1;
    for (int i = 1, x; i <= n; i++) {
        cin >> x;
        res ^= sg(x), f &= (x <= 1);
    }
    if ((f != 0 and res == 0) or (f == 0 and res != 0)) cout << "Yes\n";
    else cout << "No\n";
    return 0;
}
posted @ 2024-10-31 20:00  PHarr  阅读(2)  评论(0编辑  收藏  举报