Submission #994657

#TimeUsernameProblemLanguageResultExecution timeMemory
994657emptypringlescanJobs (BOI24_jobs)C++17
29 / 100
492 ms91216 KiB
#include <bits/stdc++.h> using namespace std; #define int long long struct node{ int s,e,m; pair<long long,int> val; long long lazy; node *l, *r; node(int S, int E){ s=S; e=E; m=(s+e)/2; val={-1e16,s}; lazy=0; if(s!=e){ l=new node(s,m); r=new node(m+1,e); } } void prop(){ if(s!=e&&lazy){ l->val.first+=lazy; l->lazy+=lazy; r->val.first+=lazy; r->lazy+=lazy; lazy=0; } } void update(int S, int E, long long V){ if(S<=s&&e<=E){ val.first+=V; lazy+=V; return; } prop(); if(E<=m) l->update(S,E,V); else if(S>m) r->update(S,E,V); else l->update(S,m,V),r->update(m+1,E,V); val=max(l->val,r->val); } void pset(int S, long long V){ if(s==e){ val.first=V; return; } prop(); if(S<=m) l->pset(S,V); else r->pset(S,V); val=max(l->val,r->val); } } *root; int n; long long mon; vector<pair<int,long long> > adj[300005]; int pre[300005],to[300005],post[300005]; int cur; void dfs(int x){ cur++; pre[x]=cur; to[cur]=x; for(auto i:adj[x]) dfs(i.first); post[x]=cur; } int done[300005]; pair<int,long long> par[300005]; int pos[300005]; int p[300005]; int find(int x){ if(p[x]==x) return x; return p[x]=find(p[x]); } void merge(int x, int y){ x=find(x); y=find(y); p[x]=y; } int32_t main(){ ios::sync_with_stdio(0); cin.tie(0); cin >> n >> mon; for(int i=0; i<=n; i++) p[i]=i; long long org=mon; memset(pos,-1,sizeof(pos)); for(int i=1; i<=n; i++){ long long a,b; cin >> a >> b; b=find(b); if(a>=0&&pos[b]!=-1){ merge(i,adj[b].back().first); adj[b].back().second+=a; } else{ adj[b].push_back({i,a}); par[i]={b,a}; } if(pos[b]==-1&&adj[b].back().second>=0) pos[b]=adj[b].back().first; else if(pos[b]!=-1&&adj[b].back().second<0) swap(adj[b][adj[b].size()-1],adj[b][adj[b].size()-2]); } dfs(0); root=new node(0,n+5); root->pset(pre[0],mon); while(true){ pair<long long,int> x=root->val; root->pset(x.second,-1e16); if(x.first<0) break; x.second=to[x.second]; //cout << x.second << ' ' << x.first << '\n'; if(x.first>=mon){ root->update(1,cur,x.first-mon); mon=x.first; int at=x.second; while(!done[at]){ done[at]=1; if(at==0) break; root->update(pre[at],post[at],-par[at].second); at=par[at].first; } for(auto i:adj[x.second]){ root->pset(pre[i.first],mon+i.second); } } else{ for(auto i:adj[x.second]){ root->pset(pre[i.first],x.first+i.second); } } } cout << mon-org; } /*6 1 3 0 -3 1 -5 0 2 1 6 3 -4 5*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...