Submission #924319

#TimeUsernameProblemLanguageResultExecution timeMemory
924319AlphaMale06Two Currencies (JOI23_currencies)C++17
100 / 100
1998 ms167552 KiB
#include <bits/stdc++.h> using namespace std; #define pb push_back #define F first #define S second #define int long long const int N = 1e5+5; struct node{ int val, cnt, lc, rc; }; node pers[50*N]; int tin[N], tout[N], h[N]; vector<pair<int, int>> cst; vector<int> adj[N]; int timer=0; int n, m, q; vector<pair<int, int>> edges; int p[N][18]; vector<int> roots; int nodenum=0; void dfs(int v, int par){ p[v][0]=par; for(int i=1; i<18; i++){ p[v][i]=p[p[v][i-1]][i-1]; } tin[v]=timer++; h[v]=h[par]+1; for(int to : adj[v]){ if(to!=par)dfs(to, v); } tout[v]=timer++; } void Build(int v, int l, int r){ if(l>r)return; nodenum++; if(l==r){ pers[v]={0, 0, -1, -1}; return; } int mid=l+r>>1; if(l<=mid){ Build(2*v, l, mid); pers[v].lc=2*v; } if(r>=mid+1){ Build(2*v+1, mid+1, r); pers[v].rc=2*v+1; } } void Update(int v, int l, int r, int ind, int val, int ps){ if(l==r){ pers[nodenum]={pers[v].val+val, pers[v].cnt+ps, -1, -1}; nodenum++; return; } int mid=l+r>>1; if(l<=ind && ind<=mid){ Update(pers[v].lc, l, mid, ind, val, ps); int child=pers[v].rc; pers[nodenum]={pers[child].val+pers[nodenum-1].val, pers[child].cnt+pers[nodenum-1].cnt, nodenum-1, child}; nodenum++; } if(mid+1<=ind && ind<=r){ Update(pers[v].rc, mid+1, r, ind, val, ps); int child=pers[v].lc; pers[nodenum]={pers[child].val+pers[nodenum-1].val, pers[child].cnt+pers[nodenum-1].cnt, child, nodenum-1}; nodenum++; } } pair<int, int> Get(int v, int l, int r, int L, int R){ if(l>R || r<L)return {0, 0}; if(l>=L && r<=R)return {pers[v].val, pers[v].cnt}; int mid=l+r>>1; pair<int, int> lft=Get(pers[v].lc, l, mid, L, R); pair<int, int> rgt=Get(pers[v].rc, mid+1, r, L, R); return {lft.F+rgt.F, lft.S+rgt.S}; } bool anc(int u, int v){ if(tin[u]<=tin[v] && tout[u]>=tout[v])return 1; return 0; } int lca(int u, int v){ if(anc(u, v))return u; if(anc(v, u))return v; for(int i=17; i>=0; i--){ if(!anc(p[u][i], v)){ u=p[u][i]; } } return p[u][0]; } signed main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> n >> m >> q; for(int i=0; i<n-1; i++){ int a, b; cin >> a >> b; edges.pb({a, b}); adj[a].pb(b); adj[b].pb(a); } dfs(1, 1); for(auto & p : edges){ if(h[p.F]>h[p.S])swap(p.F, p.S); } for(int i=0; i<m; i++){ int ind, val; cin >> ind >> val; cst.pb({val, edges[ind-1].S}); } sort(cst.begin(), cst.end()); roots.pb(0); Build(0, 0, timer-1); for(int i=0; i< m; i++){ Update(roots.back(), 0, timer-1, tin[cst[i].S], cst[i].F, 1); roots.pb(nodenum-1); Update(roots.back(), 0, timer-1, tout[cst[i].S], -cst[i].F, -1); roots.pb(nodenum-1); } while(q--){ int a, b, x, y; cin >> a >> b >> x >> y; int lc=lca(a, b); int dist=Get(roots.back(), 0, timer-1, 0, tin[a]).S+Get(roots.back(), 0, timer-1, 0, tin[b]).S-2*Get(roots.back(), 0, timer-1, 0, tin[lc]).S; int l=0; int r=roots.size()/2; int ans=1e9; while(l<=r){ int s = l+r>>1; int root=roots[2*s]; pair<int, int> lft=Get(root, 0, timer-1, 0, tin[a]); pair<int, int> rgt=Get(root, 0, timer-1, 0, tin[b]); pair<int, int> lcg=Get(root, 0, timer-1, 0, tin[lc]); if(lft.F+rgt.F-2*lcg.F<=y){ l=s+1; ans=dist-lft.S-rgt.S+2*lcg.S; } else r=s-1; } cout << max(-1ll, x-ans) << '\n'; } }

Compilation message (stderr)

currencies.cpp: In function 'void Build(long long int, long long int, long long int)':
currencies.cpp:47:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   47 |     int mid=l+r>>1;
      |             ~^~
currencies.cpp: In function 'void Update(long long int, long long int, long long int, long long int, long long int, long long int)':
currencies.cpp:64:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   64 |     int mid=l+r>>1;
      |             ~^~
currencies.cpp: In function 'std::pair<long long int, long long int> Get(long long int, long long int, long long int, long long int, long long int)':
currencies.cpp:82:14: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   82 |     int mid=l+r>>1;
      |             ~^~
currencies.cpp: In function 'int main()':
currencies.cpp:142:22: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  142 |             int s = l+r>>1;
      |                     ~^~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...