제출 #1263446

#제출 시각아이디문제언어결과실행 시간메모리
1263446denislavTwo Currencies (JOI23_currencies)C++20
28 / 100
147 ms59436 KiB
# include <iostream> # include <vector> # include <algorithm> //# define endl "\n" using namespace std; const int MAX=1e5+11,LOG=20; int n,m,q; pair<int,int> edges[MAX]; vector<int> adj[MAX]; int h[MAX]; int st[MAX][LOG]; void dfs_init(int curr, int par) { for(int nxt: adj[curr]) { if(nxt==par) continue; h[nxt]=h[curr]+1; st[nxt][0]=curr; dfs_init(nxt,curr); } } int get_lca(int u, int v) { if(h[u]<h[v]) swap(u,v); for(int j=LOG-1;j>=0;j--) { if(h[u]-(1<<j)>=h[v]) u=st[u][j]; } if(u==v) return u; for(int j=LOG-1;j>=0;j--) { if(h[u]-(1<<j)>=0 and st[u][j]!=st[v][j]) { u=st[u][j]; v=st[v][j]; } } return st[u][0]; } void lca_precalc() { dfs_init(1,0); for(int j=1;j<LOG;j++) { for(int i=1;i<=n;i++) { if(h[i]-(1<<j)<0) continue; st[i][j]=st[st[i][j-1]][j-1]; } } } pair<int,int> cp[MAX]; int real_value[MAX]; vector<int> cpts[MAX]; int cnt_cpts[MAX]; struct node { long long cost,cnt; node(){cost=0;cnt=0;} node(long long _cost, long long _cnt) {cost=_cost;cnt=_cnt;} node friend operator + (node A, node B) { return {A.cost+B.cost,A.cnt+B.cnt}; } }; const int Tsz=MAX*LOG; int ct,M; int roots[MAX]; node tree[Tsz]; int lv[Tsz]; int rv[Tsz]; int update(int pos, int d, int v, int l=1, int r=M) { if(l==r) { ct++; tree[ct]=tree[v]; tree[ct].cost+=d; tree[ct].cnt++; return ct; } int mid=(l+r)/2; if(pos<=mid) { ct++; int v2=ct; lv[v2]=update(pos,d,lv[v],l,mid); rv[v2]=rv[v]; tree[v2]=tree[lv[v2]]+tree[rv[v2]]; return v2; } else { ct++; int v2=ct; lv[v2]=lv[v]; rv[v2]=update(pos,d,rv[v],mid+1,r); tree[v2]=tree[lv[v2]]+tree[rv[v2]]; return v2; } } void dfs(int curr, int par) { cnt_cpts[curr]=cpts[curr].size()+cnt_cpts[par]; roots[curr]=roots[par]; for(int x: cpts[curr]) roots[curr]=update(x,real_value[x],roots[curr]); for(int nxt: adj[curr]) { if(nxt==par) continue; dfs(nxt,curr); } } long long query(long long k, int u, int v, int lca, int l=1, int r=M) { //cout<<l<<" "<<r<<" "<<real_value[l]<<endl; if(l==r) { long long cnt=tree[u].cnt+tree[v].cnt-tree[lca].cnt*2; return min(k/real_value[l],cnt); } long long cost=tree[u].cost+tree[v].cost-tree[lca].cost*2; long long cnt=tree[u].cnt+tree[v].cnt-tree[lca].cnt*2; int mid=(l+r)/2; if(cost>k) return query(k,lv[u],lv[v],lv[lca],l,mid); else return cnt+query(k-cost,rv[u],rv[v],rv[lca],mid+1,r); } int main() { ios_base::sync_with_stdio(0); cin.tie(0);cout.tie(0); cin>>n>>m>>q; for(int i=1;i<n;i++) { int u,v; cin>>u>>v; edges[i]={u,v}; adj[u].push_back(v); adj[v].push_back(u); } lca_precalc(); vector<pair<int,int>> temp; for(int i=1;i<=m;i++) { cin>>cp[i].first>>cp[i].second; temp.push_back({cp[i].second,i}); } sort(temp.begin(),temp.end()); int last=-1,ctt=0; for(pair<int,int> pa: temp) { if(pa.first!=last) { ctt++; real_value[ctt]=pa.first; last=pa.first; } cp[pa.second].second=ctt; } M=ctt; for(int i=1;i<=m;i++) { int u=edges[cp[i].first].first; int v=edges[cp[i].first].second; if(h[u]>h[v]) swap(u,v); cpts[v].push_back(cp[i].second); } roots[0]=0; dfs(1,0); while(q--) { int u,v,lca; long long x,y; cin>>u>>v>>x>>y; lca=get_lca(u,v); //cout<<"->"<<lca<<endl; long long ans=(cnt_cpts[u]+cnt_cpts[v]-cnt_cpts[lca]*2)-query(y,roots[u],roots[v],roots[lca]); x-=max(0LL,ans); if(x>=0) cout<<x<<"\n"; else cout<<-1<<"\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...