【CDQ分治】[P5094 [USACO04OPEN] MooFest G 加强版

P5094 [USACO04OPEN] MooFest G 加强版 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

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

    int n;
    cin >> n;

    vector<array<int, 2>> a(n);
    for (auto &[x, y] : a) {
        cin >> x >> y;
    }

    sort(a.begin(), a.end());

    i64 ans = 0;
    auto cdq = [&](auto && self, int l, int r)->void{
        if (l == r)
            return ;
        int mid = l + r >> 1;
        self(self, l, mid);
        self(self, mid + 1, r);


        sort(a.begin() + l, a.begin() + mid + 1, [](auto x, auto y) {
            if (x[1] != y[1]) return x[1] < y[1];
            return x[0] < y[0];
        });

        sort(a.begin() + mid + 1, a.begin() + r + 1, [](auto x, auto y) {
            if (x[1] != y[1]) return x[1] < y[1];
            return x[0] < y[0];
        });

        int sum1 = 0, sum2 = 0;
        for (int i = l; i <= mid; i ++)
            sum1 += a[i][1];

        int i = l, j = mid + 1;
        while (j <= r) {
            while (i <= mid && a[i][1] < a[j][1]) {
                sum1 -= a[i][1], sum2 += a[i][1];
                i ++;
            }
            int cnt1 = i - l, cnt2 = mid - i + 1;
            ans += 1ll * a[j][0] * (cnt1 * a[j][1] - sum2 + sum1 - cnt2 * a[j][1]);
            j ++;
        }

    };

    cdq(cdq, 0, n - 1);

    cout << ans << '\n';

    return 0;
}
posted @ 2024-08-06 20:23  Ke_scholar  阅读(1)  评论(0编辑  收藏  举报