Submission #1201709

#TimeUsernameProblemLanguageResultExecution timeMemory
12017098pete8Distributing Candies (IOI21_candies)C++20
67 / 100
1297 ms47000 KiB
#include "candies.h" #include<bits/stdc++.h> using namespace std; #define int long long #define pii pair<int,int> #define s second #define pb push_back #define f first #define all(x) x.begin(),x.end() const int mxn=2e5,inf=1e18,minf=-1e18; int n,q; int C[mxn+10],L[mxn+10],R[mxn+10],V[mxn+10]; struct sub1{ static vector<int32_t>solve(){ vector<int32_t>ans(n,0); for(int i=0;i<q;i++){ for(int j=L[i];j<=R[i];j++)ans[j]+=V[i]; for(int j=0;j<n;j++)ans[j]=max(0,ans[j]),ans[j]=min(ans[j],(int32_t)C[j]); } return ans; } }; struct sub2{ struct fen{ int fwk[mxn+10]; void init(){for(int i=0;i<=n;i++)fwk[i]=0;} void update(int pos,int val){ pos++; for(int i=pos;i<=n;i+=(i&-i))fwk[i]+=val; } int qry(int pos){ int sum=0; pos++; if(pos<=0)return 0; for(int i=pos;i>0;i-=(i&-i))sum+=fwk[i]; if(sum<0)assert(0); return sum; } }; static vector<int32_t>solve(){ fen t; t.init(); vector<int32_t>ans(n,0); int sum=0; for(int i=0;i<q;i++){ t.update(L[i],V[i]); t.update(R[i]+1,-V[i]); } for(int i=0;i<n;i++){ int x=min(C[i],t.qry(i)); ans[i]=(int32_t)x; } return ans; } }; int mn[4*mxn+10],mn2[4*mxn+10]; int lazy[4*mxn+10],O[4*mxn+10]; int tag1[4*mxn+10],tag2[4*mxn+10]; struct seg{ //original array //lazy , get min , set to 0 , set to C[i] //qry for the prefix <0 void pull(int pos){ mn[pos]=min(mn[pos<<1],mn[pos<<1|1]); mn2[pos]=min(mn2[pos<<1],mn2[pos<<1|1]); } void build(int pos=1,int l=0,int r=n-1){ if(l==r){ O[pos]=C[l]; mn2[pos]=O[pos]; return; } mn[pos]=0; tag1[pos]=lazy[pos]=tag2[pos]=0; int mid=l+(r-l)/2; build(pos<<1,l,mid); build(pos<<1|1,mid+1,r); pull(pos); O[pos]=min(O[pos<<1],O[pos<<1|1]); } void apply1(int x,int pos){ mn[pos]+=x; mn2[pos]-=x; lazy[pos]+=x; } void apply2(int x,int pos){ if(!x)return; //tag1 mn[pos]=0; mn2[pos]=O[pos]; tag2[pos]=lazy[pos]=0; tag1[pos]=1; } void apply3(int x,int pos){ if(!x)return; mn[pos]=O[pos]; mn2[pos]=0; tag1[pos]=lazy[pos]=0; tag2[pos]=1; } void push(int pos,int l,int r){ if(l!=r){ apply2(tag1[pos],pos<<1); apply2(tag1[pos],pos<<1|1); apply3(tag2[pos],pos<<1); apply3(tag2[pos],pos<<1|1); apply1(lazy[pos],pos<<1); apply1(lazy[pos],pos<<1|1); } lazy[pos]=tag1[pos]=tag2[pos]=0; } void update1(int ql,int qr,int val,int pos=1,int l=0,int r=n-1){ if(ql>r||qr<l)return; if(ql<=l&&r<=qr)return void(apply1(val,pos)); int mid=l+(r-l)/2; push(pos,l,r); update1(ql,qr,val,pos<<1,l,mid); update1(ql,qr,val,pos<<1|1,mid+1,r); pull(pos); } void update2(int ql,int qr,int val=1,int pos=1,int l=0,int r=n-1){ if(ql>r||qr<l)return; if(ql<=l&&r<=qr)return void(apply2(val,pos)); int mid=l+(r-l)/2; push(pos,l,r); update2(ql,qr,val,pos<<1,l,mid); update2(ql,qr,val,pos<<1|1,mid+1,r); pull(pos); } void update3(int ql,int qr,int val=1,int pos=1,int l=0,int r=n-1){ if(ql>r||qr<l)return; if(ql<=l&&r<=qr)return void(apply3(val,pos)); int mid=l+(r-l)/2; push(pos,l,r); update3(ql,qr,val,pos<<1,l,mid); update3(ql,qr,val,pos<<1|1,mid+1,r); pull(pos); } int qry1(int ql,int qr,int pos=1,int l=0,int r=n-1){ if(ql>r||qr<l)return inf; if(ql<=l&&r<=qr)return mn[pos]; int mid=l+(r-l)/2; push(pos,l,r); return min(qry1(ql,qr,pos<<1,l,mid),qry1(ql,qr,pos<<1|1,mid+1,r)); } int qry2(int ql,int qr,int pos=1,int l=0,int r=n-1){ if(ql>r||qr<l)return inf; if(ql<=l&&r<=qr)return mn2[pos]; int mid=l+(r-l)/2; push(pos,l,r); return min(qry2(ql,qr,pos<<1,l,mid),qry2(ql,qr,pos<<1|1,mid+1,r)); } }; struct sub4{ static vector<int32_t>solve(){ vector<int32_t>ans(n); vector<pii>ord; seg t; for(int i=0;i<n;i++)ord.pb({C[i],i}); sort(C,C+n); sort(all(ord)); t.build(); for(int i=0;i<q;i++){ t.update1(L[i],R[i],V[i]); int pos=-1; int l=0,r=n-1; while(l<=r){ int mid=l+(r-l)/2; if(t.qry1(mid,mid)<0)l=mid+1,pos=max(pos,mid); else r=mid-1; } if(pos!=-1)t.update2(0,pos); l=0,r=n-1,pos=-1; while(l<=r){ int mid=l+(r-l)/2; if(t.qry2(mid,mid)<0)l=mid+1,pos=max(pos,mid); else r=mid-1; } if(pos!=-1)t.update3(0,pos); } for(int i=0;i<n;i++){ ans[ord[i].s]=t.qry1(i,i); } return ans; } }; int sum[4*mxn+10]; int mx1[4*mxn+10],mx2[4*mxn+10],mxc[4*mxn+10],mn1[4*mxn+10],mnc[4*mxn+10]; struct segbeat{ //min,max,add //chmin void apply1(int pos, int x,int l,int r){ if(mx1[pos]<=x)return; //mx2[pos] <= x < mx1[pos] ->update only mx1[pos] sum[pos]-=mx1[pos]*mxc[pos]; mx1[pos]=x; sum[pos]+=mx1[pos]*mxc[pos]; if(l==r)mn1[pos]=x; else{ //case mx1 intersects mn1,mn2 if(x<=mn1[pos])mn1[pos]=x; else if(x<mn2[pos])mn2[pos]=x; } //lazy[pos]=0; } void apply2(int pos, int x,int l,int r){ if(mn1[pos]>=x)return; //mn1[pos] <= x < mn2[pos] sum[pos]-=mn1[pos]*mnc[pos]; mn1[pos]=x; sum[pos]+=mn1[pos]*mnc[pos]; if(l==r)mx1[pos]=x; else{ if(x>=mx1[pos])mx1[pos]=x; else if(x>mx2[pos])mx2[pos]=x; } //lazy[pos]=0; } void apply3(int pos,int x,int l,int r){ sum[pos]+=(r-l+1)*x; mx1[pos]+=x; if(mx2[pos]!=minf)mx2[pos]+=x; mn1[pos]+=x; if(mn2[pos]!=inf)mn2[pos]+=x; lazy[pos]+=x; } void push(int pos,int l,int r){ if(l!=r){ int mid=l+(r-l)/2; apply3(pos<<1,lazy[pos],l,mid); apply3(pos<<1|1,lazy[pos],mid+1,r); apply1(pos<<1,mx1[pos],l,mid); apply1(pos<<1|1,mx1[pos],mid+1,r); apply2(pos<<1,mn1[pos],l,mid); apply2(pos<<1|1,mn1[pos],mid+1,r); } lazy[pos]=0; } void pull(int pos,int l,int r){ sum[pos]=sum[pos<<1]+sum[pos<<1|1]; if(mx1[pos<<1]==mx1[pos<<1|1]){ mx1[pos]=mx1[pos<<1]; mx2[pos]=max(mx2[pos<<1],mx2[pos<<1|1]); mxc[pos]=mxc[pos<<1]+mxc[pos<<1|1]; } else{ if(mx1[pos<<1]>mx1[pos<<1|1]){ mx1[pos]=mx1[pos<<1]; mx2[pos]=max(mx1[pos<<1|1],mx2[pos<<1]); mxc[pos]=mxc[pos<<1]; } else{ mx1[pos]=mx1[pos<<1|1]; mx2[pos]=max(mx1[pos<<1],mx2[pos<<1|1]); mxc[pos]=mxc[pos<<1|1]; } } if(mn1[pos<<1]==mn1[pos<<1|1]){ mn1[pos]=mn1[pos<<1]; mn2[pos]=min(mn2[pos<<1],mn2[pos<<1|1]); mnc[pos]=mnc[pos<<1]+mnc[pos<<1|1]; } else{ if(mn1[pos<<1]<mn1[pos<<1|1]){ mn1[pos]=mn1[pos<<1]; mn2[pos]=min(mn1[pos<<1|1],mn2[pos<<1]); mnc[pos]=mnc[pos<<1]; } else{ mn1[pos]=mn1[pos<<1|1]; mn2[pos]=min(mn1[pos<<1],mn2[pos<<1|1]); mnc[pos]=mnc[pos<<1|1]; } } } void build(int pos=1,int l=0,int r=n-1){ lazy[pos]=0; if(l==r){ sum[pos]=mx1[pos]=mn1[pos]=0; mx2[pos]=minf; mn2[pos]=inf; mnc[pos]=mxc[pos]=1; return; } int mid=l+(r-l)/2; build(pos<<1,l,mid); build(pos<<1|1,mid+1,r); pull(pos,l,r); } //chmin void update1(int ql,int qr,int x,int pos=1,int l=0,int r=n-1){ if(l>qr||r<ql||mx1[pos]<=x)return; if(ql<=l&&r<=qr&&mx2[pos]<x)return void(apply1(pos,x,l,r)); int mid=l+(r-l)/2; push(pos,l,r); update1(ql,qr,x,pos<<1,l,mid); update1(ql,qr,x,pos<<1|1,mid+1,r); pull(pos,l,r); } void update2(int ql,int qr,int x,int pos=1,int l=0,int r=n-1){ if(l>qr||r<ql||mn1[pos]>=x)return; if(ql<=l&&r<=qr&&mn2[pos]>x)return void(apply2(pos,x,l,r)); int mid=l+(r-l)/2; push(pos,l,r); update2(ql,qr,x,pos<<1,l,mid); update2(ql,qr,x,pos<<1|1,mid+1,r); pull(pos,l,r); } void update3(int ql,int qr,int x,int pos=1,int l=0,int r=n-1){ if(l>qr||r<ql)return; if(ql<=l&&r<=qr)return void(apply3(pos,x,l,r)); int mid=l+(r-l)/2; push(pos,l,r); update3(ql,qr,x,pos<<1,l,mid); update3(ql,qr,x,pos<<1|1,mid+1,r); pull(pos,l,r); } int qry(int ql,int qr,int pos=1,int l=0,int r=n-1){ if(l>qr||r<ql)return 0; if(ql<=l&&r<=qr)return sum[pos]; int mid=l+(r-l)/2; push(pos,l,r); return qry(ql,qr,pos<<1,l,mid)+qry(ql,qr,pos<<1|1,mid+1,r); } }; struct sub3{ static vector<int32_t>solve(){ segbeat t; t.build(); for(int i=0;i<q;i++){ t.update3(L[i],R[i],V[i]); t.update1(L[i],R[i],C[0]); t.update2(L[i],R[i],0); } vector<int32_t>ans; for(int i=0;i<n;i++)ans.pb(t.qry(i,i)); return ans; } }; vector<int32_t> distribute_candies(vector<int32_t> c,vector<int32_t> l,vector<int32_t> r,vector<int32_t> v) { n=c.size(),q=l.size(); for(int i=0;i<n;i++)C[i]=c[i]; for(int i=0;i<q;i++)L[i]=l[i],R[i]=r[i],V[i]=v[i]; int yes=1,yes2=1; for(auto i:v)if(i<0)yes=0; for(int i=0;i<q;i++)yes2&=(l[i]==0&&r[i]==n-1); if(n<=2000&&q<=2000)return sub1::solve(); else if(yes)return sub2::solve(); else if(yes2)return sub4::solve(); else return sub3::solve(); } /* 10 11 440 51 41 11 1 3 108 148 14 10 0 9 60 0 9 -9 0 9 -30 0 9 41 0 9 82 0 9 69 0 9 -79 0 9 -39 0 9 72 0 9 41 */
#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...