Submission #828471

#TimeUsernameProblemLanguageResultExecution timeMemory
828471khshgTwo Currencies (JOI23_currencies)C++14
100 / 100
829 ms31200 KiB
#include<bits/stdc++.h>
using namespace std;
#define pb push_back

int N, M, Q;
vector<vector<int>> adj;
vector<int> par, sz, anc, flat, pos;
vector<pair<int, int>> e, ch;
vector<int> S, T, X;
vector<long long> Y;

void dfs_sz(int s) {
	sz[s] = 1;
	if(adj[s][0] == par[s] && (int)adj[s].size() >= 2) swap(adj[s][0], adj[s][1]);
	for(auto& u : adj[s]) {
		if(u == par[s]) continue;
		par[u] = s;
		dfs_sz(u);
		sz[s] += sz[u];
		if(sz[adj[s][0]] < sz[u]) swap(adj[s][0], u);
	}
}

void build_hld(int s, int r) {
	pos[s] = (int)flat.size();
	flat.pb(s);
	anc[s] = r;
	for(auto& u : adj[s]) {
		if(u == par[s]) continue;
		build_hld(u, (u == adj[s][0] ? r : u));
	}
}

int LCA(int a, int b) {
	if(pos[a] > pos[b]) swap(a, b);
	if(anc[a] == anc[b]) return a;
	return LCA(a, par[anc[b]]);
}

vector<long long> bit;
void update(int ind, long long val) {
	++ind;
	while(ind <= N) {
		bit[ind] += val;
		ind += ind & -ind;
	}
}
long long pref_sum(int ind) {
	++ind;
	long long sum = 0;
	while(ind > 0) {
		sum += bit[ind];
		ind -= ind & -ind;
	}
	return sum;
}
long long Query(int l, int r) {
	return pref_sum(r) - pref_sum(l - 1);
}

long long hld_path(int u, int v) {
	if(anc[u] == anc[v]) return Query(pos[v], pos[u]);
	return Query(pos[anc[u]], pos[u]) + hld_path(par[anc[u]], v);
}

int32_t main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cin >> N >> M >> Q;
	adj.resize(N);
	e.resize(N - 1);
	for(int i = 0; i + 1 < N; ++i) {
		int u, v; cin >> u >> v; --u; --v;
		e[i] = {u, v};
		adj[u].pb(v);
		adj[v].pb(u);
	}
	{ // hld
		par.resize(N);
		sz.resize(N);
		par[0] = -1;
		dfs_sz(0);
		anc.resize(N);
		pos.resize(N);
		build_hld(0, -1);
	}
	for(int i = 0; i + 1 < N; ++i) {
		if(par[e[i].second] == e[i].first) swap(e[i].first, e[i].second);
	}
	for(int i = 0; i < M; ++i) {
		int x, y; cin >> x >> y;
		ch.pb({y, e[x - 1].first});
	}
	sort(begin(ch), end(ch));
	S.resize(Q);
	T.resize(Q);
	X.resize(Q);
	Y.resize(Q);
	for(int i = 0; i < Q; ++i) {
		cin >> S[i] >> T[i] >> X[i] >> Y[i];
		--S[i]; --T[i];
	}
	vector<int> TL(Q, 0), TR(Q, M);
	while(true) {
		bool any = false;
		vector<vector<int>> Pos(M + 1);
		for(int i = 0; i < Q; ++i) {
			if(TL[i] == TR[i]) continue;
			any = true;
			int TM = (TL[i] + TR[i] + 1) / 2;
			Pos[TM].pb(i);
		}
		if(!any) break;
		bit = vector<long long>(N + 1, 0LL);
		for(int i = 0; i < M; ++i) {
			update(pos[ch[i].second], ch[i].first);
			for(auto& u : Pos[i + 1]) {
				int L = LCA(S[u], T[u]);
				long long sum = hld_path(S[u], L) + hld_path(T[u], L) - 2 * hld_path(L, L);
				if(sum <= Y[u]) {
					TL[u] = i + 1;
				} else {
					TR[u] = i;
				}
			}
		}
	}
	vector<int> ans(Q);
	bit = vector<long long>(N + 1, 0LL);
	vector<vector<int>> Pos(M + 1);
	for(int i = 0; i < Q; ++i) {
		Pos[TL[i]].pb(i);
	}
	for(int i = M; i >= 0; --i) {
		if(i < M) update(pos[ch[i].second], 1);
		for(int& u : Pos[i]) {
			if(i == M) {
				ans[u] = X[u];
				continue;
			}
			int L = LCA(S[u], T[u]);
			long long sum = hld_path(S[u], L) + hld_path(T[u], L) - 2 * hld_path(L, L);
			ans[u] = max(-1LL, X[u] - sum);
		}
	}
	for(auto& u : ans) {
		cout << u << '\n';
	}
	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...