Submission #1330927

#TimeUsernameProblemLanguageResultExecution timeMemory
1330927beepbeepsheepWind Turbines (EGOI25_windturbines)C++20
100 / 100
454 ms152188 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

typedef tree<long long, null_type, less_equal<>,
        rb_tree_tag, tree_order_statistics_node_update>
        ordered_set;
        
#define ll long long
#define ii pair<ll,ll>
#define iii tuple<ll,ll,ll>

#ifndef DEBUG
#define cerr if (0) cerr
#define endl '\n'
#endif

const ll inf=1e15;
const ll maxn=1e5+5;
const ll mod=1e9+7;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

ll mstCost;
vector<iii> edges;
set<ll> inComp[maxn];
ll par[maxn];

ll root(ll x) {
    if (par[x] == x) {
        return x;
    }
    return par[x] = root(par[x]);
}
vector<ii> segments[maxn];
void connect(ll a, ll b, ll id) {
    a = root(a);
    b = root(b);
    if (a == b) {
        return;
    }

    if (inComp[a].size() < inComp[b].size()) {
        swap(inComp[a], inComp[b]);
    }
    
    for (auto node: inComp[b]) {
        auto higher = inComp[a].lower_bound(node);
        if (higher == inComp[a].begin()) {
            segments[id].emplace_back(node, *higher);
            continue;
        }
        auto lower = higher;
        lower--;
        segments[id].emplace_back(*lower, node);
        if (higher != inComp[a].end()) {
            segments[id].emplace_back(node, *higher);
        }
    }
    
    for (auto node: inComp[b]) {
        inComp[a].emplace(node);
    }
    par[b] = a;
    mstCost += get<0>(edges[id]);
}
vector<tuple<ll, ll, ll, ll>> updates;
//right endpoint, left endpoint, old endpoint, cost
vector<iii> queries;
ll ans[maxn * 2]; //200k
ll fen[maxn];
void upd(ll x, ll v) {
    while (x < maxn) {
        fen[x] += v;
        x += (x & -x);
    }
}

ll query(ll x) {
    ll ans = 0;
    while (x) {
        ans += fen[x];
        x -= (x & -x);
    }
    return ans;
}

ll query(ll x, ll y) {
    return query(y) - query(x - 1);
}

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    ll n, m, q;
    cin >> n >> m >> q;
    for (int i = 1; i <= n; i++) {
        par[i] = i;
        inComp[i].emplace(i);
    }
    ll a, b, w;
    edges.emplace_back(-inf, -inf, -inf); //buffer element
    for (int i = 1; i <= m; i++) {
        cin >> a >> b >> w;
        a++, b++; //1-indexing
        edges.emplace_back(w, a, b);
    } 
    sort(edges.begin(), edges.end());
    for (int i = 1; i <= m; i++) {
        tie(w, a, b) = edges[i];
        connect(a, b, i);
    }
    for (int i = 1; i <= m; i++) {
        sort(segments[i].begin(), segments[i].end());
        ll cost = get<0>(edges[i]);
        for (int j = 0; j < segments[i].size(); j++) {
            ll lcurr, rcurr, lprev, rprev;
            tie(lcurr, rcurr) = segments[i][j];
            if (j == 0) {
                updates.emplace_back(rcurr, lcurr, -1, cost);
                continue;
            }
            tie(lprev, rprev) = segments[i][j - 1];
            updates.emplace_back(rcurr, lcurr, lprev, cost);
        }
    }
    sort(updates.begin(), updates.end());
    for (int i = 1; i <= q; i++) {
        cin >> a >> b;
        a++, b++;
        queries.emplace_back(b, a, i);
    }
    sort(queries.begin(), queries.end());
    ll uptr = 0, qptr = 0;
    for (int i = 1; i <= n; i++) {
        while (uptr < updates.size() && get<0>(updates[uptr]) <= i) {
            ll dontCare, newPos, oldPos, cost;
            tie(dontCare, newPos, oldPos, cost) = updates[uptr];
            upd(newPos, cost);
            if (oldPos != -1) {
                upd(oldPos, -cost);
            }
            uptr++;
        }
        while (qptr < queries.size() && get<0>(queries[qptr]) <= i) {
            ll l, r, id;
            tie(r, l, id) = queries[qptr];
            ans[id] = mstCost - query(l, r);
            qptr++;
        }
    }
    for (int i = 1; i <= q; i++) {
        cout << ans[i] << endl;
    }
    return 0;
}
#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...