Submission #1277090

#TimeUsernameProblemLanguageResultExecution timeMemory
1277090PieArmyFire (JOI20_ho_t5)C++20
100 / 100
668 ms76088 KiB
#include<bits/stdc++.h> typedef long long ll; #define pb push_back #define fr first #define sc second #define endl '\n' using namespace std; #define mid ((left+right)>>1) struct Seg{ int n,t=0; vector<ll>sum,tree; vector<ll>done; void init(int N){ n=N; sum.resize(n<<2,0); tree.resize(n<<2,0); done.resize(n<<2,0); } void push(int node){ tree[node]+=sum[node]*(t-done[node]); done[node]=t; } int l,r; void update(int tar,ll val,ll kat){ int node=1,left=0,right=n-1; while(left<right){ push(node); tree[node]+=kat*val; sum[node]+=val; node*=2; if(tar>mid){ node++; left=mid+1; } else right=mid; } push(node); tree[node]+=kat*val; sum[node]+=val; } ll qu(bool type,int node=1,int left=0,int right=-1){ if(right==-1)right=n-1; if(left>r||right<l)return 0; if(!type)push(node); if(left>=l&&right<=r)return type?sum[node]:tree[node]; return qu(type,node*2,left,mid)+qu(type,node*2+1,mid+1,right); } ll query(int left,int right){ l=left;r=right; if(l>r)return 0; return qu(false); } ll top(int left,int right){ l=left;r=right; if(l>r)return 0; return qu(true); } }; int n,q; int arr[200023],nex[200023]; ll pref[200023]; vector<pair<pair<int,int>,ll>>laser; vector<int>act[200023]; pair<int,pair<int,int>>plan[200023]; int per[200023]; ll ans[200023]; int main(){ ios_base::sync_with_stdio(23^23);cin.tie(NULL); cin>>n>>q; for(int i=1;i<=n;i++){ cin>>arr[i]; pref[i]=pref[i-1]+arr[i]; } arr[n+1]=1e9+1; for(int i=1;i<=q;i++){ int t,l,r;cin>>t>>l>>r; plan[i]={t,{l,r}}; per[i]=i; } sort(per+1,per+q+1,[&](const int &x,const int &y){ return plan[x].fr<plan[y].fr; }); vector<int>sta={n+1}; for(int i=n;i>=1;i--){ while(arr[sta.back()]<=arr[i])sta.pop_back(); nex[i]=sta.back(); sta.pb(i); } sta.clear(); for(int i=1;i<=n;i++){ while(sta.size()&&arr[sta.back()]<arr[i])sta.pop_back(); if(sta.size()&&arr[sta.back()]==arr[i]){ sta.pb(i); continue; } if(sta.size()){ laser.pb({{i,i-sta.back()},arr[sta.back()]-arr[i]}); laser.pb({{nex[i],nex[i]-sta.back()},arr[i]-arr[sta.back()]}); } sta.pb(i); } sort(laser.begin(),laser.end(),[&](const pair<pair<int,int>,ll>&x,const pair<pair<int,int>,ll>&y){ return x.fr.fr-x.fr.sc<y.fr.fr-y.fr.sc; }); int m=laser.size(); for(int i=0;i<m;i++){ act[laser[i].fr.sc].pb(i); } Seg seg,ye; seg.init(m); ye.init(n+2); int p=1; for(int tim=0;p<=q;tim++){ for(int x:act[tim]){ seg.update(x,laser[x].sc,laser[x].fr.fr); ye.update(laser[x].fr.fr-1,-laser[x].sc,laser[x].fr.fr-1); } while(p<=q&&plan[per[p]].fr==tim){ ll &res=ans[per[p]]; ll left=plan[per[p]].sc.fr,right=plan[per[p]].sc.sc; res=pref[right]-pref[left-1]; res+=ye.top(1,left-1)*(left-1)+ye.top(right+1,n)*(right); res+=ye.query(left,right); int le,ri; int l=0,r=m; while(l<r){ int mi=(l+r)/2; if(laser[mi].fr.fr-laser[mi].fr.sc+tim>=left)r=mi; else l=mi+1; } le=l; l=-1;r=m-1; while(l<r){ int mi=(l+r+1)/2; if(laser[mi].fr.fr-laser[mi].fr.sc+tim<=right)l=mi; else r=mi-1; } ri=l; res+=seg.top(0,le-1)*(left-1)+seg.top(ri+1,m-1)*right; res+=seg.query(le,ri); p++; } seg.t++; } for(int i=1;i<=q;i++){ cout<<ans[i]<<endl; } }
#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...