Submission #1223040

#TimeUsernameProblemLanguageResultExecution timeMemory
1223040minhpkTwo Currencies (JOI23_currencies)C++20
28 / 100
2343 ms134064 KiB
#include <bits/stdc++.h> #define int long long using namespace std; static const int MAXA = 1000000; int a, b, c; vector<int> z[MAXA+5]; pair<int,int> t[MAXA+5], edge[MAXA+5]; int logarit[2*MAXA+5]; int sta[MAXA*2+5], fin[MAXA*2+5], euler[MAXA*2+5], tour=0; int st[MAXA*2+5][22], high[MAXA+5]; int sta1[MAXA+5], fin1[MAXA+5], tour1=0; struct SegmentTree { int tree[4*MAXA*2+5], lazy[4*MAXA*2+5]; void build(int id,int l,int r){ tree[id]=lazy[id]=0; if(l==r) return; int m=(l+r)>>1; build(id<<1,l,m); build(id<<1|1,m+1,r); } void push(int id){ if(lazy[id]){ int v=lazy[id]; tree[id<<1]+=v; lazy[id<<1]+=v; tree[id<<1|1]+=v; lazy[id<<1|1]+=v; lazy[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){ tree[id]+=v; lazy[id]+=v; return; } push(id); int m=(l+r)>>1; update(id<<1,l,m,ql,qr,v); update(id<<1|1,m+1,r,ql,qr,v); tree[id]=tree[id<<1]+tree[id<<1|1]; } int get(int id,int l,int r,int pos){ if(l==r) return tree[id]; push(id); int m=(l+r)>>1; return pos<=m ? get(id<<1,l,m,pos) : get(id<<1|1,m+1,r,pos); } } f, f1; struct Query { int x,y,g,val; }; Query q[MAXA+5]; vector<int> v[MAXA+5]; int L[MAXA+5], R[MAXA+5], ans1[MAXA+5], ans2[MAXA+5]; void dfs(int u,int p){ sta[u]=++tour; euler[tour]=u; tour1++; sta1[u]=tour1; for(int w:z[u]) if(w!=p){ high[w]=high[u]+1; dfs(w,u); euler[++tour]=u; } fin[u]=tour; fin1[u]=tour1; } void buildst(){ for(int i=1;i<=tour;i++) st[i][0]=euler[i]; for(int j=1;j<=logarit[tour];j++){ for(int i=1;i+(1<<j)-1<=tour;i++){ int x=st[i][j-1], y=st[i+(1<<(j-1))][j-1]; st[i][j]= (high[x]<high[y]?x:y); } } } int lca(int x,int y){ int L=min(sta[x],sta[y]), R=max(sta[x],sta[y]); int k=logarit[R-L+1]; int u=st[L][k], v=st[R-(1<<k)+1][k]; return high[u]<high[v]?u:v; } int calc(int u,int v){ int su=f.get(1,1,tour1,sta1[u]); int sv=f.get(1,1,tour1,sta1[v]); int sl=f.get(1,1,tour1,sta1[lca(u,v)]); return su+sv-2*sl; } int calc1(int u,int v){ int su=f1.get(1,1,tour1,sta1[u]); int sv=f1.get(1,1,tour1,sta1[v]); int sl=f1.get(1,1,tour1,sta1[lca(u,v)]); return su+sv-2*sl; } signed main(){ ios::sync_with_stdio(false); cin.tie(nullptr); cin>>a>>b>>c; for(int i=1;i<a;i++){ int x,y; cin>>x>>y; z[x].push_back(y); z[y].push_back(x); edge[i]={x,y}; } for(int i=1;i<=b;i++) cin>>t[i].first>>t[i].second; logarit[1]=0; for(int i=2;i<=2*a;i++) logarit[i]=logarit[i>>1]+1; dfs(1,0); buildst(); for(int i=1;i<=c;i++){ cin>>q[i].x>>q[i].y>>q[i].g>>q[i].val; L[i]=1; R[i]=b; ans1[i]=ans2[i]=0; } while(true){ // ←—— clear all buckets BEFORE assigning mids for(int i=1;i<=b;i++) v[i].clear(); bool any=false; for(int i=1;i<=c;i++){ if(L[i]<=R[i]){ any=true; int mid=(L[i]+R[i])>>1; v[mid].push_back(i); } } if(!any) break; f.build(1,1,tour1); f1.build(1,1,tour1); for(int i=1;i<=b;i++){ auto [X,W] = t[i]; int u=edge[X].first, v1=edge[X].second; if(high[u]<high[v1]) swap(u,v1); f.update(1,1,tour1,sta1[u],fin1[u],W); f1.update(1,1,tour1,sta1[u],fin1[u],1); for(int qi:v[i]){ int got=calc(q[qi].x,q[qi].y); if(got<=q[qi].val){ ans1[qi]=i; ans2[qi]=calc1(q[qi].x,q[qi].y); L[qi]=i+1; } else { R[qi]=i-1; } } } } f1.build(1,1,tour1); for (int i=1;i<=b;i++){ auto [X,W] = t[i]; int u=edge[X].first, v1=edge[X].second; if(high[u]<high[v1]) swap(u,v1); f1.update(1,1,tour1,sta1[u],fin1[u],1); } for(int i=1;i<=c;i++){ int tot=calc1(q[i].x,q[i].y); int used=ans2[i]; int over=tot-used; // cout << tot << ' '; if (over>q[i].g){ cout << -1 << '\n'; }else{ cout << q[i].g - over << '\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...