제출 #972690

#제출 시각아이디문제언어결과실행 시간메모리
972690sofija6Two Currencies (JOI23_currencies)C++14
100 / 100
3165 ms179108 KiB
#include <bits/stdc++.h> #define ll long long #define MAXN 100010 #define logn 17 #define MAXV 20000010 using namespace std; ll a[MAXN],b[MAXN],in[MAXN],out[MAXN],t=1,up[MAXN][logn],leftt[MAXV],rightt[MAXV],ind=1,root[MAXN]; pair<ll,ll> val[MAXV]; map<ll,ll> valc,revvalc; vector<ll> G[MAXN]; void DFS_Init(ll i,ll p) { in[i]=t++; up[i][0]=p; for (ll j=1;j<logn;j++) up[i][j]=up[up[i][j-1]][j-1]; for (ll next : G[i]) { if (next!=p) DFS_Init(next,i); } out[i]=t++; } bool Is_Ancestor(ll u,ll v) { return in[u]<=in[v] && out[u]>=out[v]; } ll LCA(ll u,ll v) { if (Is_Ancestor(u,v)) return u; if (Is_Ancestor(v,u)) return v; for (ll i=logn-1;i>=0;i--) { if (!Is_Ancestor(up[u][i],v)) u=up[u][i]; } return up[u][0]; } void Init(ll x,ll lx,ll rx) { if (lx==rx) return; ll mid=(lx+rx)/2; leftt[x]=ind++; rightt[x]=ind++; Init(leftt[x],lx,mid); Init(rightt[x],mid+1,rx); } pair<ll,ll> Merge(pair<ll,ll> x,pair<ll,ll> y) { return {x.first+y.first,x.second+y.second}; } void Update(ll pos,pair<ll,ll> vall,ll x,ll px,ll lx,ll rx) { if (lx==rx) { val[x]=Merge(val[x],vall); return; } ll mid=(lx+rx)/2; if (pos<=mid) { if (!leftt[x] || leftt[x]==leftt[px]) { leftt[x]=ind++; val[leftt[x]]=val[leftt[px]]; } if (!rightt[x]) rightt[x]=rightt[px]; Update(pos,vall,leftt[x],leftt[px],lx,mid); } else { if (!leftt[x]) leftt[x]=leftt[px]; if (!rightt[x] || rightt[x]==rightt[px]) { rightt[x]=ind++; val[rightt[x]]=val[rightt[px]]; } Update(pos,vall,rightt[x],rightt[px],mid+1,rx); } val[x]=Merge(val[leftt[x]],val[rightt[x]]); } pair<ll,ll> Calc(ll l,ll r,ll x,ll lx,ll rx) { if (lx>r || rx<l) return {0,0}; if (lx>=l && rx<=r) return val[x]; ll mid=(lx+rx)/2; return Merge(Calc(l,r,leftt[x],lx,mid),Calc(l,r,rightt[x],mid+1,rx)); } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); ll n,m,q,S,T,X,Y; cin >> n >> m >> q; for (ll i=1;i<n;i++) { cin >> a[i] >> b[i]; G[a[i]].push_back(b[i]); G[b[i]].push_back(a[i]); } DFS_Init(1,1); for (ll i=1;i<n;i++) { if (in[a[i]]>in[b[i]]) swap(a[i],b[i]); } vector<pair<ll,ll> > val; set<ll> s; for (ll i=1;i<=m;i++) { ll p,c; cin >> p >> c; val.push_back({c,p}); s.insert(c); } sort(val.begin(),val.end()); ll cur=1; for (auto i : s) { revvalc[cur]=i; valc[i]=cur++; } ll prev=0; root[0]=ind++; Init(root[0],1,t); for (auto i : val) { ll x=valc[i.first]; if (i.first!=prev) { root[x]=ind++; prev=i.first; } Update(in[b[i.second]],{i.first,1},root[x],root[x-1],1,t); Update(out[b[i.second]],{-i.first,-1},root[x],root[x-1],1,t); } while (q--) { cin >> S >> T >> X >> Y; ll l=1,r=cur-1,mid,L=LCA(S,T),pos=0,sum=0,cnt=0; while (l<=r) { mid=(l+r)/2; pair<ll,ll> num=Merge(Calc(in[L]+1,in[S],root[mid],1,t),Calc(in[L]+1,in[T],root[mid],1,t)); if (num.first<=Y) { pos=mid; sum=num.first; cnt=num.second; l=mid+1; } else r=mid-1; } if (pos<cur-1) { ll diff=Y-sum; sum+=revvalc[pos+1]*(diff/revvalc[pos+1]); cnt+=diff/revvalc[pos+1]; } pair<ll,ll> x=Merge(Calc(in[L]+1,in[S],root[cur-1],1,t),Calc(in[L]+1,in[T],root[cur-1],1,t)); cout << max(-1ll,X-x.second+cnt) << "\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...