Submission #1298831

#TimeUsernameProblemLanguageResultExecution timeMemory
1298831Jawad_Akbar_JJTwo Currencies (JOI23_currencies)C++20
100 / 100
2537 ms48460 KiB
#include <iostream> #include <vector> #include <algorithm> using namespace std; const int N = 1<<17, K = 320, B = 320; vector<pair<int,int>> nei[N]; vector<int> vec[N], adj[N]; vector<pair<int, pair<int, int>>> ord; long long inf = 2e18, arr[N], Sum[N], y[N]; int blk[N], st[N], en[N], s[N], t[N], x[N], cr0, cr1, cr2 = 1, Cnt; int cnt1[N], cnt2[N], num[N], seen[N], Ans[N], ind[N], dv[N], lv[N], Par[N][20], hei[N]; void block(vector<int> me){ ++cr1; for (int j : me) blk[j] = cr1; } void dfs0(int u, int p){ for (auto [i, id] : nei[u]){ if (i == p) continue; lv[i] = lv[u]; for (int j : vec[id]){ adj[lv[i]].push_back(++cr2); num[cr2] = j; lv[i] = cr2; } dfs0(i, u); } } vector<int> dfs(int u, int p){ hei[u] = hei[p] + 1, Par[u][0] = p; for (int i=0;i<17;i++) Par[u][i+1] = Par[Par[u][i]][i]; st[u] = ++cr0; vector<int> me; for (int i : adj[u]){ vector<int> nw = dfs(i, u); me.insert(me.end(), nw.begin(), nw.end()); if (me.size() >= K) block(me), me = {}; } en[u] = ++cr0; me.push_back(u); return me; } int LCA(int u, int v){ if (hei[u] > hei[v]) swap(u, v); for (int i=17;i>=0;i--){ if (hei[u] + (1<<i) <= hei[v]) v = Par[v][i]; } for (int i=17;i>=0;i--){ if (Par[u][i] != Par[v][i]) v = Par[v][i], u = Par[u][i]; } return (u == v ? u : Par[u][0]); } void toggle(int id){ if (num[id] == 0) return; int cur = ind[id], d = dv[cur]; if (seen[id]){ Cnt--; cnt1[cur]--; cnt2[d]--; Sum[d] -= num[id]; } else{ Cnt++; cnt1[cur]++; cnt2[d]++; Sum[d] += num[id]; } seen[id] ^= 1; } void moveLR(int u, int v){ while (st[u] > st[v] or en[u] < en[v]){ toggle(u); u = Par[u][0]; } while (v != u){ toggle(v); v = Par[v][0]; } } signed main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); int n, m, q; cin>>n>>m>>q; for (int i=1, a, b;i<n;i++){ cin>>a>>b; nei[a].push_back({b, i}); nei[b].push_back({a, i}); } for (int i=1, p, c;i<=m;i++){ cin>>p>>c; vec[p].push_back(c); arr[i-1] = c; } sort(arr, arr + m); m = unique(arr, arr + m) - arr; for (int i=m;i<N;i++) arr[i] = inf; lv[1] = 1; dfs0(1, 0); block(dfs(1, 0)); for (int i=1;i<N;i++) ind[i] = upper_bound(arr, arr + N, num[i] - 1) - arr, dv[i] = i / B; for (int i=1;i<=q;i++){ cin>>s[i]>>t[i]>>x[i]>>y[i]; s[i] = lv[s[i]], t[i] = lv[t[i]]; ord.push_back({blk[s[i]], {t[i], i}}); } sort(ord.begin(), ord.end()); int L = 1, R = 1; for (auto [vl, pr] : ord){ int id = pr.second, cur = -1, d = -1, gld; moveLR(L, s[id]); moveLR(R, t[id]); L = s[id], R = t[id], gld = Cnt; while (arr[cur + B] != inf and y[id] >= Sum[d + 1]) d++, cur += B, y[id] -= Sum[d], gld -= cnt2[d]; while (arr[cur+1] != inf and arr[cur + 1] * cnt1[cur + 1] <= y[id]) cur++, y[id] -= arr[cur] * cnt1[cur], gld -= cnt1[cur]; Ans[id] = max(-1LL, x[id] - gld + y[id] / arr[++cur]); } for (int i=1;i<=q;i++) cout<<Ans[i]<<' '; cout<<'\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...