제출 #1335386

#제출 시각아이디문제언어결과실행 시간메모리
1335386gelastropodWind Turbines (EGOI25_windturbines)C++20
100 / 100
795 ms153836 KiB
#pragma GCC optimize("O3,inline")
#include <bits/stdc++.h>
using namespace std;
#define int long long

int val = 0;
vector<int> p, tree, ans;
vector<set<int>> ss;
vector<queue<pair<int, int>>> rangs;

int fin(int n) {
    if (p[n] == n) return n;
    return p[n] = fin(p[n]);
}

void join(int a, int b, int m) {
    rangs.push_back({});
    a = fin(a), b = fin(b);
    if (a == b) return;
    val += m;
    if (ss[a].size() > ss[b].size()) swap(ss[a], ss[b]);
    for (int i : ss[a]) {
        auto _iter1 = ss[b].lower_bound(i), _iter2 = ss[a].lower_bound(i);
        if (_iter1 != ss[b].begin()) {
            _iter1--;
            if (_iter2 == ss[a].begin() || *(--_iter2) < *_iter1) rangs.back().push({*_iter1, i});
        }
        auto iter1 = ss[b].upper_bound(i), iter2 = ss[a].upper_bound(i);
        if (iter1 != ss[b].end() && (iter2 == ss[a].end() || *iter2 > *iter1)) rangs.back().push({i, *iter1});
    }
    for (int i : ss[a]) ss[b].insert(i);
    p[a] = b;
}

void upd(int n, int x) {
    while (n < tree.size()) {
        tree[n] += x;
        n += n & (-n);
    }
}

int qry(int a) {
    int ans = 0;
    while (a) {
        ans += tree[a];
        a -= a & (-a);
    }
    return ans;
}

signed main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int N, M, Q, a, b, c; cin >> N >> M >> Q;
    vector<pair<int, pair<int, int>>> edges;
    vector<pair<pair<int, int>, int>> quers;
    tree.resize(2 * N + 5, 0);
    ans.resize(Q, 0);
    for (int i = 0; i < M; i++) {
        cin >> a >> b >> c;
        edges.push_back({ c, {a, b} });
    }
    for (int i = 0; i < Q; i++) {
        cin >> a >> b;
        quers.push_back({ {a, b}, i });
    }
    sort(edges.begin(), edges.end());
    sort(quers.begin(), quers.end());
    for (int i = 0; i < N; i++) {
        p.push_back(i);
        ss.push_back({ i });
    }
    for (int i = 0; i < M; i++) join(edges[i].second.first, edges[i].second.second, edges[i].first);
    priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>, greater<pair<int, pair<int, int>>>> pq;
    for (int i = 0; i < M; i++) {
        if (rangs[i].empty()) continue;
        pq.push({ rangs[i].front().first, {i, rangs[i].front().second + 1} });
        upd(rangs[i].front().second + 1, edges[i].first);
        rangs[i].pop();
    }
    auto iter = quers.begin();
    for (int i = 0; i < N; i++) {
        while (iter != quers.end() && iter->first.first == i) ans[iter->second] = qry(iter->first.second + 1), iter++;
        while (pq.size() && pq.top().first <= i) {
            auto j = pq.top(); pq.pop();
            upd(j.second.second, -edges[j.second.first].first);
            if (rangs[j.second.first].empty()) continue;
            pq.push({ rangs[j.second.first].front().first, {j.second.first, rangs[j.second.first].front().second + 1} });
            upd(rangs[j.second.first].front().second + 1, edges[j.second.first].first);
            rangs[j.second.first].pop();
        }
    }
    for (int i : ans) cout << val - i << '\n';
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...