Hướng dẫn giải của Anh nông dân chăm chỉ ojboy


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
#include <bits/stdc++.h>
using namespace std;

using int64 = long long;

int64 count_two_robots_multiset(const vector<int64>& w) {
    int n = (int)w.size();

    vector<int64> pref(n + 1, 0);
    for (int i = 0; i < n; i++) {
        pref[i + 1] = pref[i] + w[i];
    }

    // The input guarantees total sum is zero.
    assert(pref[n] == 0);

    // Rotate so that all prefixes are non-negative.
    // This makes the circular structure linear.
    int cut = 0;
    for (int i = 0; i < n; i++) {
        if (pref[i] < pref[cut]) {
            cut = i;
        }
    }

    vector<int64> a(n);
    for (int i = 0; i < n; i++) {
        a[i] = w[(cut + i) % n];
    }

    // P[i] = signed prefix before station i in the rotated array.
    // D[i] = total sink demand before station i in the rotated array.
    vector<int64> P(n + 1, 0), D(n + 1, 0);
    for (int i = 0; i < n; i++) {
        P[i + 1] = P[i] + a[i];
        D[i + 1] = D[i] + max<int64>(0, -a[i]);
    }

    int64 ans = 0;

    // Count pairs of two distinct starting positions.
    // In the rotated order, count pairs (i, j) with i < j.
    int j = 1;
    for (int i = 0; i < n; i++) {
        j = max(j, i + 1);

        int64 need = D[i] + P[i];
        while (j < n && D[j] < need) {
            j++;
        }

        // Every j, j + 1, ..., n - 1 works with i.
        ans += n - j;
    }

    // Count pairs where both robots start at the same position.
    // This is possible exactly when a single robot starting there can solve everything,
    // i.e. the corresponding prefix is a global minimum. After this rotation, those are
    // exactly the positions with P[i] == 0.
    for (int i = 0; i < n; i++) {
        if (P[i] == 0) {
            ans++;
        }
    }

    return ans;
}

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

    int t;
    cin >> t;

    while (t--) {
        int n;
        cin >> n;

        vector<int64> a(n);
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }

        cout << count_two_robots_multiset(a) << '\n';
    }

    return 0;
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.