Submission #1046581

#TimeUsernameProblemLanguageResultExecution timeMemory
1046581TurkhuuTwo Currencies (JOI23_currencies)C++17
100 / 100
2220 ms149192 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; int N, M, Q, timer; vector<int> sz, pos, dep, par, top; vector<vector<int>> adj; struct S { S *l, *r; ll s; S() {l = r = nullptr; s = 0;} S(ll a) {l = r = nullptr; s = a;} S(S *x) : l(x->l), r(x->r), s(x->s) {} S(S *u, S *v) : l(u), r(v), s(0) { if (l) s += l->s; if (r) s += r->s; } }; vector<S*> roots; S* build(int l, int r) { if (l + 1 == r) return new S(0LL); int m = (l + r) / 2; return new S(build(l, m), build(m, r)); } S* upd(S* i, int l, int r, int j, ll v) { if (l + 1 == r) return new S(i->s + v); int m = (l + r) / 2; return j < m ? new S(upd(i->l, l, m, j, v), i->r) : new S(i->l, upd(i->r, m, r, j, v)); } ll qry(S* i, int l, int r, int L, int R) { if (R <= l || r <= L) return 0; if (L <= l && r <= R) return i->s; int m = (l + r) / 2; return qry(i->l, l, m, L, R) + qry(i->r, m, r, L, R); } void init(int x) { sz[x] = 1; for (auto &y : adj[x]) { adj[y].erase(find(adj[y].begin(), adj[y].end(), par[y] = x)); dep[y] = dep[x] + 1; init(y); sz[x] += sz[y]; if (sz[y] > sz[adj[x][0]]) swap(y, adj[x][0]); } } void dfs(int x) { pos[x] = timer++; for (auto y : adj[x]) { top[y] = y == adj[x][0] ? top[x] : y; dfs(y); } } ll path(int x, int y, int z) { ll s = 0; for (; top[x] != top[y]; x = par[top[x]]) { if (dep[top[x]] < dep[top[y]]) swap(x, y); s += qry(roots[z], 0, N, pos[top[x]], pos[x] + 1); } if (dep[x] > dep[y]) swap(x, y); return s += qry(roots[z], 0, N, pos[x] + 1, pos[y] + 1); } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> N >> M >> Q; sz.resize(N); pos.resize(N); dep.resize(N); adj.resize(N); top.resize(N); par.resize(N, -1); vector<pair<int, int>> edges(N - 1); for (int i = 0; i < N - 1; i++) { int a, b; cin >> a >> b; a--, b--; edges[i] = {a, b}; adj[a].push_back(i); adj[b].push_back(i); } vector<int> w(N - 1); { function<void(int, int)> dfs = [&](int x, int p) { for (auto &y : adj[x]) { int i = y; auto [u, v] = edges[y]; y = x ^ u ^ v; if (y == p) continue; w[i] = y; dfs(y, x); } }; dfs(0, -1); } init(0); dfs(0); roots.push_back(build(0, N)); vector<pair<int, int>> ch(M); for (int i = 0; i < M; i++) { int e, s; cin >> e >> s; e--; ch[i] = {s, w[e]}; } sort(ch.begin(), ch.end()); for (auto [s, i] : ch) { roots.push_back(upd(roots.back(), 0, N, pos[i], s)); } vector<vector<int>> a(M + 1); vector<int> S(Q), T(Q), X(Q), ans(Q); vector<ll> Y(Q); for (int i = 0; i < Q; i++) { cin >> S[i] >> T[i] >> X[i] >> Y[i]; S[i]--, T[i]--; int lo = 0, hi = M; while (lo < hi) { int mi = (lo + hi + 1) / 2; path(S[i], T[i], mi) <= Y[i] ? lo = mi : hi = mi - 1; } a[lo].push_back(i); } roots.resize(1); for (int i = M; i >= 0; i--) { if (i < M) { auto [s, j] = ch[i]; roots.push_back(upd(roots.back(), 0, N, pos[j], 1)); } for (auto j : a[i]) { ans[j] = max<ll>(-1, X[j] - path(S[j], T[j], M - i)); } } for (int i = 0; i < Q; i++) cout << ans[i] << "\n"; return 6/22; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...