乒乒球

思考什么什么不写

题意

共记录了 \(n\) 颗球胜负关系,给出 \(n\) 和其长度为 \(k\) 的循环节,求最终比分。

思路

首先特判答案为 \(0:0\) 的情况:循环节与 ABABBA 同构。然后暴力找比分的周期,因为令任意位置作为一局起点时该局终点唯一,反之亦然,所以复杂度 \(O(\left| state \right|k)\)

Code

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

signed main() {
    cin.tie(0) -> sync_with_stdio(false);
    ll n; int k; cin >> n >> k;
    string s; cin >> s; s = ' ' + s;
    auto ck = [&]() {
        vector<int> v(k + 1);
        for (int i = 1; i <= k; i++) v[i] = v[i - 1] + 2 * (s[i] == 'A') - 1;
        return abs(v[1] - v[k]) == 1 && find(v.begin(), v.end(), 2) == v.end();
    };
    if (ck()) {
        cout << "0:0" << '\n';
        return 0;
    }
    vector<int> inv(k + 1);
    auto P = [&](int i) {
        return (i - 1) % k + 1;
    };
    array<unordered_map<int, int>, 2> C;
    array<int, 2> c{0, 0};
    int now = 1;
    while (!inv[P(now)]) {
        inv[P(now)] = now;
        int a = 0, b = 0;
        for (int j = now; ; j++) {
            a += s[P(j)] == 'A';
            b += s[P(j)] == 'B';
            if (max(a, b) >= 11 && abs(a - b) >= 2) {
                C[0][j] = (c[0] += a > b);
                C[1][j] = (c[1] += b > a);
                now = j + 1;
                break;
            }
        }
    }
    int start = inv[P(now)];
    int interval = now - start;
    ll repeat = (n - start + 1) / interval;
    ll patternCntA = (C[0][now - 1] - C[0][start - 1]) * repeat;
    ll patternCntB = (C[1][now - 1] - C[1][start - 1]) * repeat;
    int remain = start - 1 + (n - start + 1) % interval;
    int remainCntA = 0, remainCntB = 0;
    int a = 0, b = 0;
    for (int i = 1; i <= remain; i++) {
        a += s[P(i)] == 'A';
        b += s[P(i)] == 'B';
        if (max(a, b) >= 11 && abs(a - b) >= 2) {
            remainCntA += a > b;
            remainCntB += b > a;
            a = b = 0;
        }
    }
    cout << patternCntA + remainCntA << ':' << patternCntB + remainCntB << '\n';
    return 0;
}

reference:

Leetcode 466. 统计重复个数【寻找循环节,双百提交,解释非常详细】- MD_

posted @ 2024-07-09 17:54  wkh2008  阅读(11)  评论(0编辑  收藏  举报