Submission #1223011

#TimeUsernameProblemLanguageResultExecution timeMemory
1223011minhpkTwo Currencies (JOI23_currencies)C++20
0 / 100
25 ms47428 KiB
#include <bits/stdc++.h> #define int long long using namespace std; static const int MAXN = 1000000; int N, M, Q; vector<int> adj[MAXN+5]; pair<int,int> checkpoint[MAXN+5]; pair<int,int> edgeList[MAXN+5]; int log2table[2*MAXN+5]; int euler[2*MAXN+5], timer = 0; int st[2*MAXN+5][22], depthArr[MAXN+5]; int firstPos[MAXN+5]; int tour1 = 0, in1[MAXN+5], out1[MAXN+5]; int LCA(int u, int v) { int l = firstPos[u], r = firstPos[v]; if (l > r) swap(l, r); int k = log2table[r - l + 1]; int a = st[l][k], b = st[r - (1<<k) + 1][k]; return depthArr[a] < depthArr[b] ? a : b; } void dfs(int u, int p, int d) { depthArr[u] = d; firstPos[u] = ++timer; euler[timer] = u; for (int v: adj[u]) { if (v == p) continue; dfs(v, u, d+1); euler[++timer] = u; } in1[u] = ++tour1; out1[u] = tour1; } void buildLCA() { for (int i = 1; i <= timer; i++) { st[i][0] = euler[i]; } int K = log2table[timer]; for (int j = 1; j <= K; j++) { for (int i = 1; i + (1<<j) - 1 <= timer; i++) { int x = st[i][j-1], y = st[i + (1<<(j-1))][j-1]; st[i][j] = depthArr[x] < depthArr[y] ? x : y; } } } struct SegTree { vector<int> t, lz; int n; void init(int _n) { n = _n; t.assign(4*n+4, 0); lz.assign(4*n+4, 0); } void apply(int id, int val) { t[id] += val; lz[id] += val; } void push(int id) { if (lz[id]) { apply(id<<1, lz[id]); apply(id<<1|1, lz[id]); lz[id] = 0; } } void update(int id, int l, int r, int ql, int qr, int v) { if (qr < l || r < ql) return; if (ql <= l && r <= qr) { apply(id, v); return; } int mid = (l+r)>>1; push(id); update(id<<1, l, mid, ql, qr, v); update(id<<1|1, mid+1, r, ql, qr, v); t[id] = t[id<<1] + t[id<<1|1]; } int queryPoint(int id, int l, int r, int pos) { if (l == r) return t[id]; int mid = (l+r)>>1; push(id); return pos <= mid ? queryPoint(id<<1, l, mid, pos) : queryPoint(id<<1|1, mid+1, r, pos); } }; SegTree segW, segS; struct Query { int u, v, G, Sneed; }; Query Qs[MAXN+5]; int lo[MAXN+5], hi[MAXN+5], ansCp[MAXN+5], usedSilver[MAXN+5]; vector<int> bucket[MAXN+5]; int calcSilver(int u, int v) { int su = segW.queryPoint(1,1,tour1,in1[u]); int sv = segW.queryPoint(1,1,tour1,in1[v]); int sl = segW.queryPoint(1,1,tour1,in1[LCA(u,v)]); return su + sv - 2*sl; } int calcCount(int u, int v) { int su = segS.queryPoint(1,1,tour1,in1[u]); int sv = segS.queryPoint(1,1,tour1,in1[v]); int sl = segS.queryPoint(1,1,tour1,in1[LCA(u,v)]); return su + sv - 2*sl; } signed main(){ ios::sync_with_stdio(false); cin.tie(nullptr); cin >> N >> M >> Q; for(int i=1;i<N;i++){ int A,B; cin>>A>>B; adj[A].push_back(B); adj[B].push_back(A); edgeList[i] = {A,B}; } for(int i=1;i<=M;i++){ cin>>checkpoint[i].first>>checkpoint[i].second; } log2table[1]=0; for(int i=2;i<=2*N;i++){ log2table[i] = log2table[i>>1] + 1; } dfs(1,0,0); buildLCA(); for(int i=1;i<=Q;i++){ cin>>Qs[i].u>>Qs[i].v>>Qs[i].G>>Qs[i].Sneed; lo[i]=1; hi[i]=M; ansCp[i]=0; usedSilver[i]=0; } bool cont=true; while(cont){ cont=false; for(int i=1;i<=M;i++) bucket[i].clear(); for(int i=1;i<=Q;i++){ if(lo[i]<=hi[i]){ cont=true; bucket[(lo[i]+hi[i])>>1].push_back(i); } } if(!cont) break; segW.init(tour1); segS.init(tour1); for(int i=1;i<=M;i++){ int ei = checkpoint[i].first; auto [u,v] = edgeList[ei]; if(depthArr[u] < depthArr[v]) swap(u,v); segW.update(1,1,tour1, in1[u], out1[u], checkpoint[i].second); segS.update(1,1,tour1, in1[u], out1[u], 1); for(int qi: bucket[i]){ int needS = calcSilver(Qs[qi].u, Qs[qi].v); if(needS <= Qs[qi].Sneed){ ansCp[qi] = i; usedSilver[qi] = needS; lo[qi] = i+1; } else { hi[qi] = i-1; } } } } for(int i=1;i<=Q;i++){ if(ansCp[i]==0){ cout << -1 << "\n"; } else { int silverUsed = usedSilver[i]; int needGold = max(0LL, silverUsed - Qs[i].Sneed); cout << (Qs[i].G - needGold) << "\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...