Submission #994701

#TimeUsernameProblemLanguageResultExecution timeMemory
994701emptypringlescanJobs (BOI24_jobs)C++17
40 / 100
519 ms100692 KiB
#include <bits/stdc++.h> using namespace std; #define int long long struct node{ int s,e,m; pair<long long,pair<int,bool> > val; pair<long long,int> leaf; long long lazy; node *l, *r; node(int S, int E){ s=S; e=E; m=(s+e)/2; val={-1e16,{s,0}}; leaf={-1e16,-1}; 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->leaf.first+=lazy; r->leaf.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; leaf.first+=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); leaf=max(l->leaf,r->leaf); } void pset(int S, long long V, bool L){ if(s==e){ val.first=V; val.second.second=L; if(L) leaf={V,s}; else leaf={-1e16,-1}; return; } prop(); if(S<=m) l->pset(S,V,L); else r->pset(S,V,L); val=max(l->val,r->val); leaf=max(l->leaf,r->leaf); } } *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; } long long dp(int x){ long long ret=0; for(auto i:adj[x]){ ret+=max(dp(i.first)+i.second,0ll); } return ret; } void take(pair<long long,pair<int,bool> > x){ root->update(1,cur,x.first-mon); mon=x.first; int at=x.second.first; while(!done[at]){ done[at]=1; root->update(pre[at],post[at],-par[at].second); root->pset(pre[at],-1e16,0); at=par[at].first; } } 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); par[adj[b].back().first].second+=a; 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]); } if(mon==1e18){ cout << dp(0); return 0; } dfs(0); root=new node(0,n+5); root->pset(pre[0],mon,1); while(true){ pair<long long,pair<int,bool> > x=root->val; if(x.first<0) break; x.second.first=to[x.second.first]; //cout << x.second.first << ' ' << x.first << ' ' << x.second.second <<'\n'; if(x.first>=mon){ take(x); if(!x.second.second) continue; } else if(!x.second.second){ pair<long long,int> l=root->leaf; x={l.first,{to[l.second],1}}; root->pset(pre[x.second.first],x.first,0); } else root->pset(pre[x.second.first],x.first,0); if(x.first<0) break; //cout << x.second.first << ' ' << x.first << ' ' << x.second.second <<'\n'; for(auto i:adj[x.second.first]){ root->pset(pre[i.first],i.second+x.first,1); } } cout << mon-org; } /*6 1 3 0 -3 1 -5 0 2 1 6 3 -4 5*/ /*10 0 -3 0 1 1 2 1 1 1 2 0 -1 5 2 6*/
#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...