제출 #1272688

#제출 시각아이디문제언어결과실행 시간메모리
1272688PieArmyTwo Currencies (JOI23_currencies)C++20
100 / 100
514 ms33720 KiB
#include<bits/stdc++.h> typedef long long ll; #define pb push_back #define fr first #define sc second #define endl '\n' using namespace std; typedef pair<ll,ll> pl; pl operator+(const pl x,const pl y){ return pl{x.fr+y.fr,x.sc+y.sc}; } struct Fen{ int n; vector<pl>tree; void init(int N){ n=N; tree.resize(0); tree.resize(n+1,pl{0,0}); } void update(int tar,pl x){ while(tar<=n){ tree[tar]=tree[tar]+x; tar+=(tar&-tar); } } pl query(int tar){ pl res={0,0}; while(tar>0){ res=res+tree[tar]; tar-=(tar&-tar); } return res; } }; int n,m,q; vector<int>komsu[100023]; pl road[100023],check[100023]; int s[100023],t[100023]; int us[100023]; ll gold[100023],silv[100023]; int par[100023][17]; int in[100023],out[100023]; int tim=1; Fen fen; void dfs(int pos){ for(int i=1;i<17;i++){ par[pos][i]=par[par[pos][i-1]][i-1]; } in[pos]=tim++; for(int x:komsu[pos]){ if(x==par[pos][0])continue; par[x][0]=pos; dfs(x); } out[pos]=tim++; } int lca(int x,int y){ if(in[x]<=in[y]&&out[x]>in[y])return x; for(int i=17-1;i>=0;i--){ if(in[par[x][i]]<=in[y]&&out[par[x][i]]>in[y])continue; x=par[x][i]; } return par[x][0]; } int main(){ ios_base::sync_with_stdio(23^23);cin.tie(NULL); cin>>n>>m>>q; for(int i=1;i<n;i++){ int x,y;cin>>x>>y; komsu[x].pb(y); komsu[y].pb(x); road[i]={x,y}; } for(int i=1;i<=m;i++){ cin>>check[i].sc>>check[i].fr; } for(int i=1;i<=q;i++){ cin>>s[i]>>t[i]>>gold[i]>>silv[i]; } sort(check+1,check+m+1); par[1][0]=1; dfs(1); for(int i=1;i<n;i++){ if(in[road[i].fr]<in[road[i].sc]){ swap(road[i].fr,road[i].sc); } } for(int i=1;i<=m;i++){ check[i].sc=road[check[i].sc].fr; } for(int i=1;i<=q;i++){ us[i]=lca(s[i],t[i]); } queue<pair<pl,vector<int>>>Q; { vector<int>v(q); iota(v.begin(),v.end(),1); Q.push({{0,m},v}); } int ind=m+1; while(Q.size()){ int l=Q.front().fr.fr,r=Q.front().fr.sc; vector<int>v=Q.front().sc; Q.pop(); if(!v.size())continue; int mi=(l+r+1)/2; if(ind>mi){ fen.init(tim); for(int i=1;i<=m;i++){ fen.update(in[check[i].sc],{0,1}); fen.update(out[check[i].sc],{0,-1}); } ind=0; } while(ind<mi){ ind++; fen.update(in[check[ind].sc],{check[ind].fr,-1}); fen.update(out[check[ind].sc],{-check[ind].fr,1}); } if(l==r){ for(int x:v){ gold[x]-=fen.query(in[s[x]]).sc+fen.query(in[t[x]]).sc-2*fen.query(in[us[x]]).sc; } continue; } vector<int>sag,sol; for(int x:v){ if(silv[x]>=fen.query(in[s[x]]).fr+fen.query(in[t[x]]).fr-2*fen.query(in[us[x]]).fr){ sol.pb(x); } else sag.pb(x); } v.clear(); Q.push({{l,mi-1},sag}); Q.push({{mi,r},sol}); } for(int i=1;i<=q;i++){ if(gold[i]<0)cout<<-1<<endl; else cout<<gold[i]<<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...