CF2200E题解

传送门:https://codeforces.com/contest/2200/problem/E

博弈论,先找必赢或者必输局面。找到Alice的必赢局面显然比较简单,当存在两个顺序颠倒的素数就是Alice的必赢局面。由于Alice先手可以先行构造这样的局面。首先特判掉一开始就单调不减的情况。

  • 如果存在一个数 \(num\),有两个不同素因子 \(p\) 和 \(q\),其中 \(p<q\)。我们可以把当前的数替换成 \(num/p, p\)。这样我们保证了 \(p\) 出现在比他大的素因子后面,而前面一个数永远存在 \(q\) 这个因子使得序列无法单调不减。Alice胜。

  • 如果所有数都只有一个素因子时,我们只需要判断这些素因子是否单调不减。

证明:如果单调不减Bob胜,反之Alice。设前一个数为 \(q^a\),后一个数为 \(p^b \ (p<q)\)。当 \(b=0\),已经有单独的 \(p\) 出现在仅由 \(q\) 这个素因子构成的数后面,序列永远无法单调减。否则,Alice在后一个数中拆一个 \(p\) 出来,也就是把这两个数拆成 \(q^a,p,p^{b-1}\)。这样也能构成 \(b=0\) 的情况,所以Alice胜。当素因子单调不减时,最后必定会拆成所有素因子构成的序列,结果也单调不减,Bob胜。

需要注意的就是:因为序列中可能包含有 \(1\) ,所以此题要认为序列中的 \(1\) 为单独的素因子。当然特判 \(1\) 是否出现在非 \(1\) 的后面也可以。

#include <bits/stdc++.h>

const int N = 5e5 + 1;

using namespace std;

int a[N];

void solve() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i) cin >> a[i];
    bool flag = true;
    for (int i = 2; i <= n; ++i) if (a[i - 1] > a[i]) flag = false;
    if (flag) {
        cout << "Bob" << '\n';
        return;
    }
    int pre = 0;
    bool f = false;
    for (int i = 1; i <= n; ++i) {
        if (a[i] == 1 && f) {
            cout << "Alice" << '\n';
            return;
        }
        if (a[i] > 1) f = true;
        flag = false;
        int p = 0;
        for (int j = 2; j * j <= a[i]; ++j) {
            if (a[i] % j == 0) {
                if (flag) {
                    cout << "Alice" << '\n';
                    return;
                }
                flag = true, p = j;
                while (a[i] % j == 0) a[i] /= j;
            }
        }
        if (a[i] > 1) {
            if (flag) {
                cout << "Alice" << '\n';
                return;
            }
            p = a[i];
        }
        if (p < pre) {
            cout << "Alice" << '\n';
            return;
        }
        pre = p;
    }
    cout << "Bob" << '\n';
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T;
    cin >> T;
    while (T--) solve();
    return 0;
}
posted @ 2026-03-01 18:21  Jefferyzzzz  阅读(15)  评论(0)    收藏  举报