Submission #729598

#TimeUsernameProblemLanguageResultExecution timeMemory
729598abcvuitunggioTwo Currencies (JOI23_currencies)C++17
100 / 100
4321 ms145576 KiB
#include <bits/stdc++.h> #define int long long using namespace std; struct edge{ int a,b; }e[100001]; struct checkpoint{ int p,c; }ch[100001]; struct citizen{ int s,t,x,y,idx; }c[100001]; struct T{ int gold,silver; }; int n,m,q,res[100001]; int p[100001][20],tin[100001],tout[100001],t;//lca int root[100001],pos[100001],sz[100001],chain[100001],chainsize[100001],id;//hld int l[100001],r[100001],kq[100001];//binary search vector <int> ke[100001]; vector <citizen> ve[100001]; vector <T> st[100001]; T operator +(T a, T b){ return {a.gold+b.gold,a.silver+b.silver}; } void update(int node, int l, int r, int x, int g, int s, int idx){ if (l>x||r<x||l>r) return; if (l==r){ st[idx][node].gold+=g; st[idx][node].silver+=s; return; } int mid=(l+r)>>1; update(node<<1,l,mid,x,g,s,idx); update(node<<1|1,mid+1,r,x,g,s,idx); st[idx][node]=st[idx][node<<1]+st[idx][node<<1|1]; } void update(int i, int mode){ if (!i) return; int u=ch[i].p; update(1,1,chainsize[chain[u]],pos[u],(mode?1:-1),(mode?0:ch[i].c),chain[u]); } T get(int node, int l, int r, int u, int v, int idx){ if (l>v||r<u||l>r||u>v) return {0,0}; if (l>=u&&r<=v) return st[idx][node]; int mid=(l+r)>>1; return get(node<<1,l,mid,u,v,idx)+get(node<<1|1,mid+1,r,u,v,idx); } void dfs(int u=1, int par=1){ tin[u]=++t; sz[u]=1; for (int v:ke[u]) if (v!=par){ p[v][0]=u; for (int i=1;i<20;i++) p[v][i]=p[p[v][i-1]][i-1]; dfs(v,u); sz[u]+=sz[v]; } tout[u]=t; } bool isancestor(int u, int v){ return (tin[u]<=tin[v]&&tout[u]>=tout[v]); } int lca(int u, int v){ if (isancestor(u,v)) return u; if (isancestor(v,u)) return v; for (int i=19;i>=0;i--) if (p[u][i]&&!isancestor(p[u][i],v)) u=p[u][i]; return p[u][0]; } void dfs2(int u=1){ if (!pos[u]){ pos[u]=1; root[u]=u; chain[u]=++id; } chainsize[chain[u]]++; int mx=0,bigchild=-1; for (int v:ke[u]) if (v!=p[u][0]) if (mx<sz[v]){ mx=sz[v]; bigchild=v; } if (bigchild!=-1){ pos[bigchild]=pos[u]+1; chain[bigchild]=chain[u]; root[bigchild]=root[u]; } for (int v:ke[u]) if (v!=p[u][0]) dfs2(v); } T get(int u, int v){ int l=lca(u,v); T res; res.gold=res.silver=0; while (u){ if (isancestor(root[u],l)){ res=res+get(1,1,chainsize[chain[u]],pos[l]+1,pos[u],chain[u]); break; } res=res+get(1,1,chainsize[chain[u]],1,pos[u],chain[u]); u=p[root[u]][0]; } swap(u,v); while (u){ if (isancestor(root[u],l)){ res=res+get(1,1,chainsize[chain[u]],pos[l]+1,pos[u],chain[u]); break; } res=res+get(1,1,chainsize[chain[u]],1,pos[u],chain[u]); u=p[root[u]][0]; } return res; } int32_t main(){ ios_base::sync_with_stdio(NULL);cin.tie(nullptr); cin >> n >> m >> q; for (int i=1;i<n;i++){ cin >> e[i].a >> e[i].b; ke[e[i].a].push_back(e[i].b); ke[e[i].b].push_back(e[i].a); } for (int i=1;i<=m;i++) cin >> ch[i].p >> ch[i].c; sort(ch+1,ch+m+1,[](checkpoint a, checkpoint b){ return a.c<b.c; }); for (int i=1;i<=q;i++){ cin >> c[i].s >> c[i].t >> c[i].x >> c[i].y; c[i].idx=i; l[i]=1; r[i]=m; } dfs(); dfs2(); for (int i=1;i<n;i++) if (e[i].a==p[e[i].b][0]) swap(e[i].a,e[i].b); for (int i=1;i<=m;i++) ch[i].p=e[ch[i].p].a; for (int i=1;i<=id;i++) st[i].resize(chainsize[i]*4+1); while (true){ bool change=false; for (int i=1;i<=id;i++) for (T &j:st[i]) j.gold=j.silver=0; for (int i=1;i<=m;i++){ ve[i].clear(); update(i,1); } for (int i=1;i<=q;i++) if (l[i]<=r[i]){ ve[(l[i]+r[i])>>1].push_back(c[i]); change=true; } if (!change) break; for (int i=1;i<=m;i++){ update(i,0); for (auto j:ve[i]){ T t=get(j.s,j.t); if (t.silver<=j.y){ kq[j.idx]=i; l[j.idx]=i+1; } else r[j.idx]=i-1; } } } for (int i=1;i<=id;i++) for (T &j:st[i]) j.gold=j.silver=0; for (int i=1;i<=m;i++){ ve[i].clear(); update(i,1); } for (int i=1;i<=q;i++) ve[kq[i]].push_back(c[i]); for (int i=0;i<=m;i++){ update(i,0); for (auto j:ve[i]){ T t=get(j.s,j.t); res[j.idx]=max(j.x-t.gold,-1LL); } } for (int i=1;i<=q;i++) cout << res[i] << '\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...