Submission #1139460

#TimeUsernameProblemLanguageResultExecution timeMemory
1139460NK_Reconstruction Project (JOI22_reconstruction)C++20
0 / 100
0 ms328 KiB
// Success consists of going from failure to failure without loss of enthusiasm
#include <bits/stdc++.h>

using namespace std;

#define nl '\n'
#define pb push_back
#define sz(x) int(x.size())
#define bk back()

using ll = long long;
template<class T> using V = vector<T>;
template<class T, size_t SZ> using AR = array<T, SZ>;
using vi = V<int>;
using vl = V<ll>;
using T = AR<int, 3>;

const ll INF = 1e15;

struct DSU {
	int N; vi e; V<T> took; void init(int n) { N = n; e = vi(N, -1); took = {}; }
	int get(int x) { return e[x] < 0 ? x : e[x] = get(e[x]); }
	bool unite(int x, int y, int w) {
		int rx = get(x), ry = get(y);
		if (rx == ry) return 0;
		// cout << "ADDED: " << x << " " << y << " => " << w << endl;
		took.pb(T{w, x, y});
		if (e[rx] > e[ry]) swap(rx, ry);
		e[rx] += e[ry]; e[ry] = rx; return 1;
	}
};	

int main() {
	cin.tie(0)->sync_with_stdio(0);
	
	int N, M; cin >> N >> M;

	V<T> E; for(int i = 0; i < M; i++) {
		int u, v, w; cin >> u >> v >> w; --u, --v;
		E.pb(T{w, u, v});
	}

	sort(begin(E), end(E));

	V<DSU> P = {DSU()}, S = {DSU()}; DSU D; ll ans = 0;

	set<ll> done; V<V<AR<int, 2>>> answer(M);
	int Q, cur = 0; cin >> Q;
	for(int q = 0; q < Q; q++) {
		int x; cin >> x;

		while(x > E[cur][0]) cur++;

		answer[min(cur, M - 1)].pb(AR<int, 2>{x, q});
	}

	auto tri = [&](T e, ll at) { 
		if (D.unite(e[1], e[2], e[0])) {
			// cout << "TOOK: " << e[0] << " " << e[1] << " " << e[2] << endl;
			ans += abs(e[0] - at); 
		}
	};

	vl ANS(Q);
	function<void(int, int)> dnc = [&](int l, int r) {
		if (l == r) {
			S.bk.took.insert(begin(S.bk.took), E[l]);
			// cout << "L: " << E[l][0] << " " << E[l][1] << " " << E[l][2] << endl;

			int np = sz(P.bk.took), ns = sz(S.bk.took);
			for(auto& [at, i] : answer[l]) {
		
				// cout << "COMPUTE: " << l << " " << r << " -> " << at << " " << i << endl;

				D.init(N); ans = 0;
				int p = 0, s = 0;

				// cout << "START -> " << np << " " << ns << endl;

				while(p < np || s < ns) {
					if (sz(D.took) == N - 1) break;
					// cout << p << " " << s << endl;
					if (p == np) tri(S.bk.took[s++], at);
					else if (s == ns) tri(P.bk.took[p++], at);
					else if (abs(S.bk.took[s][0] - at) < abs(P.bk.took[p][0] - at)) {
						tri(S.bk.took[s++], at);
					} else {
						tri(P.bk.took[p++], at);
					}
				}

				// cout << "DONE => " << ans << endl;
				ANS[i] = ans;
			}

			return;
		}

		// cout << l << " <-----> " << r << endl;

		int m = (l + r) / 2;

		// go to [l, m] and [m + 1, r]

		// go to [l, m] | add m + 1 -> r to the suffix ST
		D.init(N);
		for(int x = m + 1; x <= r; x++) D.unite(E[x][1], E[x][2], E[x][0]);
		for(auto& e : S.bk.took) {
			// cout << "SUFFIX EX: " << e[1] << " " << e[2] << " " << e[0] << endl;
			D.unite(e[1], e[2], e[0]);
			if (sz(D.took) == N - 1) break;
		}

		S.pb(D); dnc(l, m); S.pop_back();


		// go to [m + 1, r] | add m -> l to the prefix ST
		D.init(N);
		for(int x = m; x >= l; x--) D.unite(E[x][1], E[x][2], E[x][0]);
		for(auto& e : P.bk.took) {
			// cout << "PREFIX EX: " << e[1] << " " << e[2] << " " << e[0] << endl;
			D.unite(e[1], e[2], e[0]);
			if (sz(D.took) == N - 1) break;
		}

		P.pb(D); dnc(m + 1, r); P.pop_back();
	};

	dnc(0, M - 1);

	for(auto& x : ANS) cout << x << nl;

	exit(0-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...