제출 #1335423

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

using ii = pair<int, int>;
using iii = pair<int, ii>;

constexpr int MAXN = 100000 + 5;
constexpr int INF = 1e18 + 5;
constexpr int LOG = 20;

vector<ii> segs[MAXN];

struct DSU {
	vector<int> p;
	vector<set<int>> comps;
	
	DSU(int n): p(n), comps(n) {
		iota(p.begin(), p.end(), 0);
		for (int i = 0; i < n; ++i) comps[i].emplace(i);
	}
	
	int get(int x) {
		return x == p[x] ? x : p[x] = get(p[x]);
	}
	
	bool unite(int a, int b, int edgeid) {
		a = get(a); b = get(b);
		if (a == b) return false;
		
		if (comps[a].size() < comps[b].size()) swap(a, b);
		
		vector<ii> towardsLeft;
		vector<ii> towardsRight;
		for (int i : comps[b]) {
			auto it1 = comps[a].upper_bound(i);
			auto it2 = it1; it2--;
			
			if (it1 != comps[a].begin()) {
				int l = *it2;
				towardsLeft.emplace_back(l, i);
			}
			
			if (it1 != comps[a].end()) {
				int r = *it1;
				if (!towardsRight.empty() && towardsRight.back().second == r) towardsRight.pop_back();
				towardsRight.emplace_back(i, r);
			}
		}

		for (auto [l, r] : towardsLeft) {
			segs[r].emplace_back(edgeid, l);
		}

		for (auto [l, r] : towardsRight) {
			segs[r].emplace_back(edgeid, l);
		}

		for (int i : comps[b]) comps[a].emplace(i);

		p[b] = a;
		
		return true;
	}
};

int FT[MAXN];

void point_upd(int p, int v) {
	p += 2;
	for (; p < MAXN; p += (p & -p)) FT[p] += v;
}

void range_upd(int l, int r, int v) {
	point_upd(l, v);
	point_upd(r+1, -v);
}

int pref_qry(int p) {
	p += 2;
	int ans = 0;
	for (; p > 0; p &= p - 1) ans += FT[p];
	return ans;
}

signed main() {
	ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);

	int N, M, Q; cin >> N >> M >> Q;
	DSU dsu(N);

	vector<iii> edges(M);
	for (int i = 0; i < M; ++i) {
		cin >> edges[i].second.first >> edges[i].second.second >> edges[i].first;
	}
	
	sort(edges.begin(), edges.end());
	
	int cost = 0;
	for (int i = 0; i < M; ++i) {
		auto [w, edge] = edges[i];
		if (dsu.unite(edge.first, edge.second, i)) {
			cost += w;
		}
	}
	
	vector<int> last(M, -1);
	vector<vector<ii>> queriesEndingAt(N);
	vector<int> answers(Q);
	
	for (int i = 0; i < Q; ++i) {
		int l, r; cin >> l >> r;
		queriesEndingAt[r].emplace_back(l, i);
	}
	
	for (int i = 0; i < N; ++i) {
		for (auto [idx, l] : segs[i]) {
			if (last[idx] != -1) range_upd(0, last[idx], -edges[idx].first);
			range_upd(0, l, edges[idx].first);
			last[idx] = l;
		}
		
		for (auto [l, idx] : queriesEndingAt[i]) {
			answers[idx] = cost - pref_qry(l);
		}
	}
	
	for (int i = 0; i < Q; ++i) cout << answers[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...