Submission #1092477

#TimeUsernameProblemLanguageResultExecution timeMemory
1092477Nom_mxmxTwo Currencies (JOI23_currencies)C++14
100 / 100
771 ms45900 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define endl '\n' #define fi first #define se second #define pb push_back struct path { int x, y, lca; ll g, s; }; struct binS { int lo, hi, mid; }; const int N = 1e5+3; const int B = (1<<18); const int L = 17; pair<ll, int> T[2*B+3]; pair<int, int> edg[N]; pair<int, int> price[N]; vector<int> g[N]; vector<int> mids[N]; binS bin[N]; path p[N]; int jump[N][L+1]; int ans[N]; int d[N]; int siz[N]; int pre[N]; int n, m, q; int ind; void dfs(int v, int p) { pre[v] = ++ind; siz[v] = 1; d[v] = d[p]+1; jump[v][0] = p; for(auto u:g[v]) { if(u == p) continue; dfs(u, v); siz[v] += siz[u]; } } int lca(int a, int b) { if(d[a] < d[b]) swap(a, b); for(int i=L; i>=0; i--) if(d[jump[a][i]] >= d[b]) a = jump[a][i]; for(int i=L; i>=0; i--) { if(jump[a][i] != jump[b][i]) { a = jump[a][i]; b = jump[b][i]; } } if(a == b) return a; return jump[a][0]; } void clr() { for(int i=1; i<2*B+3; i++) T[i] = {0, 0}; } void upd(int a, int b, int x, int v=1, int l=1, int r=B-1) { if(l > b || r < a) return; if(l >= a && r <= b) { T[v].fi += x; T[v].se += 1; return; } upd(a, b, x, 2*v, l, (l+r)/2); upd(a, b, x, 2*v+1, (l+r)/2+1, r); } pair<ll, int> cnt(int v) { pair<ll, int> a = {0, 0}; v += B-1; while(v > 0) { a.fi += T[v].fi; a.se += T[v].se; v /= 2; } return a; } void parallel() { int lft = q; while(lft) { clr(); for(int i=1; i<=m; i++) { // numer krawedzi jest w price[i].se; int curEdg = price[i].se; int num = edg[curEdg].fi; if(d[edg[curEdg].fi] < d[edg[curEdg].se]) num = edg[curEdg].se; upd(pre[num], pre[num] + siz[num] - 1, price[i].fi); for(auto x:mids[i]) { pair<ll, int> v1 = cnt(pre[p[x].x]); pair<ll, int> v2 = cnt(pre[p[x].y]); pair<ll, int> lc = cnt(pre[p[x].lca]); pair<ll, int> path = {v1.fi + v2.fi - 2*lc.fi, v1.se + v2.se - 2*lc.se}; if(p[x].s >= path.fi) { bin[x].lo = i; ans[x] = path.se; } else bin[x].hi = i-1; bin[x].mid = (bin[x].lo + bin[x].hi + 1)/2; if(bin[x].lo == bin[x].hi) lft--; else mids[bin[x].mid].pb(x); } mids[i].clear(); mids[i].shrink_to_fit(); } } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> n >> m >> q; for(int i=1; i<n; i++) { cin >> edg[i].fi >> edg[i].se; g[edg[i].fi].pb(edg[i].se); g[edg[i].se].pb(edg[i].fi); } dfs(1, 0); for(int i=1; i<=L; i++) for(int j=1; j<=n; j++) jump[j][i] = jump[jump[j][i-1]][i-1]; for(int i=1; i<=m; i++) cin >> price[i].se >> price[i].fi; sort(price+1, price+m+1); for(int i=1; i<=q; i++) { cin >> p[i].x >> p[i].y >> p[i].g >> p[i].s; p[i].lca = lca(p[i].x, p[i].y); bin[i].lo = 0; bin[i].hi = m; bin[i].mid = (m+1)/2; mids[bin[i].mid].pb(i); } parallel(); for(int i=1; i<=q; i++) { pair<ll, int> v1 = cnt(pre[p[i].x]); pair<ll, int> v2 = cnt(pre[p[i].y]); pair<ll, int> lc = cnt(pre[p[i].lca]); pair<ll, int> path = {v1.fi + v2.fi - 2*lc.fi, v1.se + v2.se - 2*lc.se}; int Ans = p[i].g - (path.se - ans[i]); cout << max(Ans, -1) << endl; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...