[2020CCPC Network Competition] 1005 Lunch (HDU6892)

Topic link

General meaning

Have nnn piles of stones, each pile hasmi m_imiOne stone, two people take turns to operate. If anyone can’t operate, the game ends.
The operation is: select one of the piles and divide the pile into t (t ≠ 1) t(t \neq 1)tt=1 ) Pile, and the number of stones in each pile is the same

Ideas

The key to the exchange of winners and losers

Consider the case where the number of stones is 8

The number of stones is 8 8At 8 , you can split as follows

Number value It takes several operations to directly convert to 1.
2 4 2
4 2 4
8 1 0

It can be noted that 8 88 can only take out an even number of values, of course this and its prime factor is only2 22 Relevant
Note that no matter what kind of split, the number of operations increased is an even number, that is, there isno exchange of winners and losers

Consider the case where the number of stones is 81

The number of stones is 81 81At 8 1 , you can split as follows

Number value It takes several operations to directly convert to 1.
3 27 3
9 9 9
27 3 27
81 1 0

It can be noted that 81 818 1 can only split an odd number of values, and no matter which split, the number of operations increased is an odd number, that is, the winner will be exchanged

Conclusion of the exchange of winners and losers

When a pile of stones is divided into an odd number, the exchange occurs winning hand, or winning hands are not exchanged
an odd number but may be decomposed into, the prime factor to this value Africa 22The number of values ​​of 2 ,
and every time you can take away any number of odd prime factors or take away all2 2 ofthis value.2 factors
will become a simplenimgame

in conclusion

Convert each value to the power of all odd prime factors of this value and add whether this value is a multiple of 2, and then play the nim game.

AC code

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1e5 + 100;
bool notprime[MAXN]; // 值为 false 表示素数,值为 true 表示非素数
vector<int> prime;

void init() {
    
    
    memset(notprime, false, sizeof(notprime));
    notprime[0] = notprime[1] = true;
    for (int i = 2; i < MAXN; i++)
        if (!notprime[i]) {
    
    
            prime.push_back(i);
            if (i > MAXN / i)
                continue; // 防止后面 i*i 溢出 (或者 i,j 用 long long)
            // 直接从 i*i 开始就可以,小于 i 倍的已经筛选过了, 注意是 j += i
            for (int j = i * i; j < MAXN; j += i)
                notprime[j] = true;
        }
}

int frac(int n) {
    
    
    int sum = 0, flag = 0;
    for (auto item : prime) {
    
    
        if (n < item) break;
        while (n % item == 0) {
    
    
            if (item != 2) sum++;
            else flag = 1;
            n /= item;
        }
    }
    if (n > 1) sum++;
    return sum + flag;
}

void solve() {
    
    
    init();
    int _;
    cin >> _;
    for (int ts = 0; ts < _; ++ts) {
    
    
        int n;
        cin >> n;
        int res = 0;
        for (int i = 0; i < n; ++i) {
    
    
            int tmp;
            cin >> tmp;
            res ^= frac(tmp);
        }
        cout << (res ? "W" : "L") << endl;
    }
}

signed main() {
    
    
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
#ifdef ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    signed localTestCount = 1, localReadPos = cin.tellg();
    char localTryReadChar;
    do {
    
    
        if (localTestCount > 20)
            throw runtime_error("Check the stdin!!!");
        auto startClockForDebug = clock();
        solve();
        auto endClockForDebug = clock();
        cout << "Test " << localTestCount << " successful" << endl;
        cerr << "Test " << localTestCount++ << " Run Time: "
             << double(endClockForDebug - startClockForDebug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    } while (localReadPos != cin.tellg() && cin >> localTryReadChar && localTryReadChar != '$' &&
             cin.putback(localTryReadChar));
#else
    solve();
#endif
    return 0;
}

Guess you like

Origin blog.csdn.net/m0_43448982/article/details/108693710