제출 #964472

#제출 시각아이디문제언어결과실행 시간메모리
964472YassirSalamaTwo Currencies (JOI23_currencies)C++17
40 / 100
5031 ms106168 KiB
#include <bits/stdc++.h> using namespace std; const int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1}; #define endl "\n" #define int ll using ull=unsigned long long; using ll=long long; using pii=pair<int,int>; const int mod=1e9+7; #define OVL(x,s) for(auto y:x) cout<<y<<s; cout<<"\n"; template <typename T> istream& operator>>(istream& is, vector<T> &a) { copy_n(istream_iterator<T>(is), a.size(), a.begin()); return is;} #ifdef IOI void dbg_out() { cout << endl; } template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << H; dbg_out(T...); } #define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__); #else #define dbg(...) 1337; #endif #define pb push_back #define F first #define S second #define all(v) v.begin(),v.end() const int mxn=1e5+100; const int LOGN=20; vector<pair<int,int>> ed; vector<vector<int>> f; vector<int> v[mxn]; int depth[mxn]; int pos[mxn]; int top[mxn]; int sz[mxn]; int up[mxn][LOGN+1]; map<pii,int> mp; map<int,pii> mp2; vector<vector<int>> queries; void dfs(int node,int par){ depth[node]=depth[par]+1; up[node][0]=par; for(int i=1;i<=LOGN;i++){ up[node][i]=up[up[node][i-1]][i-1]; } sz[node]=1; for(auto x:v[node]){ if(x==par){continue;} dfs(x,node); sz[node]+=sz[x]; } } int LCA(int a,int b){ if(depth[a]<depth[b]) swap(a,b); int d=depth[a]-depth[b]; for(int i=LOGN;i>=0;i--){ if(d&(1<<i)) a=up[a][i]; } if(a==b) return a; for(int i=LOGN;i>=0;i--){ if(up[a][i]!=up[b][i]){ a=up[a][i]; b=up[b][i]; } } return up[a][0]; } int c=1; int cID=1; void HLD(int node,int par,int cID){ top[node]=cID; pos[node]=c; c++; int bst=0; int b=-1; for(auto x:v[node]){ if(x==par) continue; if(b<sz[x]){ b=sz[x]; bst=x; } } if(b!=-1){ HLD(bst,node,cID); } for(auto x:v[node]){ if(x==par||x==bst) continue; HLD(x,node,x); } } int tree[4*mxn][2]; void update(int node,int l,int r,int ql,int x){ if(l==r){ tree[node][0]+=x; tree[node][1]+=(x>0?1:-1); return; } int mid=(l+r)/2; if(ql<=mid) update(node<<1,l,mid,ql,x); else update(node<<1|1,mid+1,r,ql,x); tree[node][0]=tree[node<<1][0]+tree[node<<1|1][0]; tree[node][1]=tree[node<<1][1]+tree[node<<1|1][1]; } int query(int node,int l,int r,int ql,int qr){ if(ql>qr) return 0; if(ql<=l&&r<=qr) return tree[node][0]; int ans=0; int mid=(l+r)/2; if(ql<=mid) ans+=query(node<<1,l,mid,ql,qr); if(qr>mid) ans+=query(node<<1|1,mid+1,r,ql,qr); return ans; } int query1(int node,int l,int r,int ql,int qr){ if(ql>qr) return 0; if(ql<=l&&r<=qr) return tree[node][1]; int ans=0; int mid=(l+r)/2; if(ql<=mid) ans+=query1(node<<1,l,mid,ql,qr); if(qr>mid) ans+=query1(node<<1|1,mid+1,r,ql,qr); return ans; } map<pii,int> updated,upp; pair<int,int> qq(int u,int v){ pair<int,int> ans(0,0); //u is an ancestor of v. while(top[u]!=top[v]){ int l=top[v]; l=pos[l]; l++; int r=pos[v]; // dbg(pos[top[v]],r,u,v) ans.F+=query(1,1,mxn,l,r); ans.S+=query1(1,1,mxn,l,r); v=top[v]; int t=up[v][0]; if(updated.count({t,v})){ ans.F+=updated[{t,v}]; ans.S+=upp[{t,v}]; } v=up[v][0]; } int l=pos[u]; l++; int r=pos[v]; ans.F+=query(1,1,mxn,l,r); ans.S+=query1(1,1,mxn,l,r); return ans; } pair<int,int> qv(int u,int v){ int l=LCA(u,v); pair<int,int> ans(0,0); pair<int,int> a=qq(l,u); pair<int,int> b=qq(l,v); // dbg(l,u,v,a.S,b.S) ans.F=a.F+b.F; ans.S=a.S+b.S; return ans; } int sum[mxn]; int nm[mxn]; int ans[mxn]; void bs(int l,int r,vector<vector<int>> &queries){ if(l>r) return; if(queries.empty()) return; vector<vector<int>> ok,nok; int mid=(l+r)/2; for(int i=l;i<=mid;i++){ int a=f[i][0]; int b=f[i][1]; int c=f[i][2]; if(up[a][0]==b) swap(a,b); update(1,1,mxn,pos[b],c); updated[{a,b}]+=c; upp[{a,b}]++; } for(auto x:queries){ int s=x[0]; int t=x[1]; pair<int,int> as=qv(s,t); if(sum[x[4]]>=as.F){ sum[x[4]]-=as.F; nm[x[4]]-=as.S; ans[x[4]]=mid; ok.pb(x); }else{ nok.pb(x); } } for(int i=l;i<=mid;i++){ int a=f[i][0]; int b=f[i][1]; int c=f[i][2]; if(up[a][0]==b) swap(a,b); update(1,1,mxn,pos[b],-c); updated.erase(make_pair(a,b)); upp.erase(make_pair(a,b)); } if(l==r){ for(auto x:queries){ if(nm[x[4]]>x[2]) ans[x[4]]=-1; else ans[x[4]]=x[2]-nm[x[4]]; } return; } bs(l,mid,nok);vector<vector<int>>().swap(nok); bs(mid+1,r,ok);vector<vector<int>>().swap(ok); } signed main(){ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL); int n,m,q; cin>>n>>m>>q; for(int i=0;i+1<n;i++){ int a,b; cin>>a>>b; v[a].pb(b); v[b].pb(a); ed.pb({a,b}); mp[{a,b}]=mp[{b,a}]=i; mp2[i]={a,b}; } for(int i=0;i<m;i++){ int p,c; cin>>p>>c; p--; auto [a,b]=mp2[p]; f.pb({a,b,c}); } sort(all(f),[&](const auto &a,const auto &b ){ return a[2]<b[2]; }); for(int i=0;i<q;i++){ int s,t,x,y; cin>>s>>t>>x>>y; queries.pb({s,t,x,y,i}); sum[i]=y; } dfs(1,1); HLD(1,1,1); for(auto x:f){ int a=x[0]; int b=x[1]; int c=x[2]; if(up[a][0]==b) swap(a,b); updated[{a,b}]+=c; upp[{a,b}]++; update(1,1,mxn,pos[b],c); } for(auto x:queries){ int s=x[0]; int t=x[1]; nm[x[4]]=qv(s,t).S; } for(auto x:f){ int a=x[0]; int b=x[1]; int c=x[2]; if(up[a][0]==b) swap(a,b); updated.erase(make_pair(a,b)); upp.erase(make_pair(a,b)); update(1,1,mxn,pos[b],-c); } bs(0,m-1,queries); for(auto x:queries){ cout<<ans[x[4]]<<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...