제출 #1055274

#제출 시각아이디문제언어결과실행 시간메모리
1055274Huseyn123사탕 분배 (IOI21_candies)C++17
100 / 100
2126 ms47208 KiB
#include "candies.h" #include <bits/stdc++.h> #include <vector> #define INF LLONG_MAX #define pb push_back using namespace std; typedef long long ll; vector<vector<int>> s,e; struct segtree_min{ vector<ll> mins; vector<ll> lazy; int size; void init(int n){ size=1; while(size<n){ size*=2; } mins.assign(2*size,0LL); lazy.assign(2*size,0LL); } void build(int x,int lx,int rx,vector<int> &a){ if(rx-lx==1){ if(lx<(int)a.size()){ mins[x]=a[lx]; } return; } int m=(lx+rx)/2; build(2*x+1,lx,m,a); build(2*x+2,m,rx,a); mins[x]=min(mins[2*x+1],mins[2*x+2]); } void build(vector<int> &a){ build(0,0,size,a); } void propogate(int x,int lx,int rx){ if(rx-lx==1){ return; } mins[2*x+1]+=lazy[x]; mins[2*x+2]+=lazy[x]; lazy[2*x+1]+=lazy[x]; lazy[2*x+2]+=lazy[x]; lazy[x]=0; } void upd(int x,int lx,int rx,int l,int r,int v){ propogate(x,lx,rx); if(rx<=l || lx>=r){ return; } if(lx>=l && rx<=r){ mins[x]+=v; lazy[x]+=v; return; } int m=(lx+rx)/2; upd(2*x+1,lx,m,l,r,v); upd(2*x+2,m,rx,l,r,v); mins[x]=min(mins[2*x+1],mins[2*x+2]); } void upd(int l,int r,int v){ return upd(0,0,size,l,r,v); } ll get(int x,int lx,int rx,int l,int r){ propogate(x,lx,rx); if(rx<=l || lx>=r){ return INF; } if(lx>=l && rx<=r){ return mins[x]; } int m=(lx+rx)/2; ll s1,s2; s1=get(2*x+1,lx,m,l,r); s2=get(2*x+2,m,rx,l,r); return min(s1,s2); } ll get(int l,int r){ return get(0,0,size,l,r); } }; struct segtree_max{ vector<ll> maxs; vector<ll> lazy; int size; void init(int n){ size=1; while(size<n){ size*=2; } maxs.assign(2*size,0LL); lazy.assign(2*size,0LL); } void build(int x,int lx,int rx,vector<int> &a){ if(rx-lx==1){ if(lx<(int)a.size()){ maxs[x]=a[lx]; } return; } int m=(lx+rx)/2; build(2*x+1,lx,m,a); build(2*x+2,m,rx,a); maxs[x]=max(maxs[2*x+1],maxs[2*x+2]); } void build(vector<int> &a){ build(0,0,size,a); } void propogate(int x,int lx,int rx){ if(rx-lx==1){ return; } maxs[2*x+1]+=lazy[x]; maxs[2*x+2]+=lazy[x]; lazy[2*x+1]+=lazy[x]; lazy[2*x+2]+=lazy[x]; lazy[x]=0; } void upd(int x,int lx,int rx,int l,int r,int v){ propogate(x,lx,rx); if(rx<=l || lx>=r){ return; } if(lx>=l && rx<=r){ maxs[x]+=v; lazy[x]+=v; return; } int m=(lx+rx)/2; upd(2*x+1,lx,m,l,r,v); upd(2*x+2,m,rx,l,r,v); maxs[x]=max(maxs[2*x+1],maxs[2*x+2]); } void upd(int l,int r,int v){ return upd(0,0,size,l,r,v); } ll get(int x,int lx,int rx,int l,int r){ propogate(x,lx,rx); if(rx<=l || lx>=r){ return -INF; } if(lx>=l && rx<=r){ return maxs[x]; } int m=(lx+rx)/2; ll s1,s2; s1=get(2*x+1,lx,m,l,r); s2=get(2*x+2,m,rx,l,r); return max(s1,s2); } ll get(int l,int r){ return get(0,0,size,l,r); } }; vector<int> distribute_candies(vector<int> c, vector<int> l, vector<int> r, vector<int> v) { int n = c.size(); int q = l.size(); vector<int> ans(n); s.resize(n); e.resize(n); for(int i=0;i<q;i++){ s[l[i]].pb(i); e[r[i]].pb(i); } segtree_min stmin; segtree_max stmax; stmin.init(q); stmax.init(q); for(int i=0;i<n;i++){ for(auto x:s[i]){ stmin.upd(x,q,v[x]); stmax.upd(x,q,v[x]); } int l,r,mid; l=0; r=q-1; while(l<r){ mid=(l+r+1)/2; if(stmax.get(mid,q)-stmin.get(mid,q)>=c[i]){ l=mid; } else{ r=mid-1; } } ll res=0; if(stmax.get(l,q)-stmin.get(l,q)>=c[i]){ if(stmax.get(l,l+1)==stmax.get(l,q)){ res=-stmin.get(l,q); if(l+1<q){ ll mx=stmax.get(l+1,q); if(res+mx>c[i]){ res=c[i]-mx; } } } else{ res=c[i]-stmax.get(l,q); if(l+1<q){ ll mn=stmin.get(l+1,q); if(res+mn<0){ res=-mn; } } } } else{ ll mx=stmax.get(0,q); ll mn=stmin.get(0,q); if(mx>c[i]){ res=c[i]-mx; } if(mn<0){ res=-mn; } } ans[i]=res+stmax.get(q-1,q); for(auto x:e[i]){ stmin.upd(x,q,-v[x]); stmax.upd(x,q,-v[x]); } } /* ll val[q+1]; pair<ll,ll> mn[q+1],mx[q+1]; val[0]=0; for(int i=1;i<=q;i++){ val[i]=v[i-1]; val[i]+=val[i-1]; } mn[q]={val[q],q}; mx[q]={val[q],q}; for(int i=q-1;i>=1;i--){ mn[i]={val[i],(ll)i}; mx[i]={val[i],(ll)i}; if(mn[i+1].first<=val[i]){ mn[i]=mn[i+1]; } if(mx[i+1].first>=val[i]){ mx[i]=mx[i+1]; } } int ind=1; while(ind<=q){ e.push_back({mx[ind].first-mn[ind].first,mx[ind].second,mn[ind].second}); ind=max(mx[ind].second,mn[ind].second)+1; } int sz=(int)e.size(); for(int i=0;i<n;i++){ int l,r,mid; l=0; r=sz-1; while(l<r){ mid=(l+r)/2; if(e[mid][0]<c[i]){ r=mid; } else{ l=mid+1; } } ll res=0; if(e[l][0]<c[i]){ if(l){ if(e[l-1][1]>e[l-1][2]){ res+=c[i]-val[e[l-1][1]]; } else{ res-=val[e[l-1][2]]; } } if(val[e[l][1]]+res>c[i]){ res=c[i]-val[e[l][1]]; } if(val[e[l][2]]+res<0){ res=-val[e[l][2]]; } } else{ if(e[sz-1][1]>e[sz-1][2]){ res+=c[i]-val[e[sz-1][1]]; } else{ res-=val[e[sz-1][2]]; } } s[i]=val[q]+res; } */ return ans; }
#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...