2019牛客暑期多校训练营(第四场)C sequence 单调栈+线段树维护区间最大子段和

mac2022-06-30  22

#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll maxn=3e6+10; const ll inf=1e18; struct node{ ll maxx,minn; }tree[maxn<<2]; int a[maxn],b[maxn],pl[maxn],pr[maxn]; //int q1[maxn],q2[maxn]; ll sum[maxn]; void build(int l,int r,int rt){ if(l==r){ tree[rt].maxx=sum[l]; tree[rt].minn=sum[l]; return; } int mid=l+r>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); tree[rt].maxx=max(tree[rt<<1].maxx,tree[rt<<1|1].maxx); tree[rt].minn=min(tree[rt<<1].minn,tree[rt<<1|1].minn); } ll qmax(int l,int r,int ql,int qr,int rt){ if(ql<=l&&r<=qr){ return tree[rt].maxx; } int mid=l+r>>1; ll ans=-inf; if(ql<=mid){ ans=max(ans,qmax(l,mid,ql,qr,rt<<1)); } if(qr>=mid+1){ ans=max(ans,qmax(mid+1,r,ql,qr,rt<<1|1)); } return ans; } ll qmin(int l,int r,int ql,int qr,int rt){ // cout<<l<<" "<<r<<endl; if(ql<=l&&r<=qr){ return tree[rt].minn; } int mid=l+r>>1; ll ans=inf; if(ql<=mid){ ans=min(ans,qmin(l,mid,ql,qr,rt<<1)); } if(qr>=mid+1){ ans=min(ans,qmin(mid+1,r,ql,qr,rt<<1|1)); } return ans; } stack<int>s; int main(){ int n;scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } for(int i=1;i<=n;i++){ scanf("%d",&b[i]); sum[i]=sum[i-1]+(ll)b[i]; // update(0,n,i,sum[i],1); } build(0,n,1); // cout<<"asdasd"<<endl; for(int i=1;i<=n;i++){ while(!s.empty()&&a[s.top()]>=a[i])s.pop(); if(s.empty())pl[i]=0; else pl[i]=s.top(); s.push(i); } while(!s.empty())s.pop(); for(int i=n;i>=1;i--){ while(!s.empty()&&a[s.top()]>=a[i])s.pop(); if(s.empty())pr[i]=n; else pr[i]=s.top()-1; s.push(i); } for(int i=1;i<=n;i++){ int l=pl[i],r=pr[i]; ll ml,mr; // prllf("%d %d\n",mr,ml); if(a[i]>0){ mr=qmax(0,n,i,r,1); // cout<<"asd"<<endl; ml=qmin(0,n,l,i-1,1); ans=max(ans,(ll)(a[i]*(mr-ml))); } else{ mr=qmin(0,n,i,r,1); ml=qmax(0,n,l,i-1,1); ans=max(ans,(ll)(a[i]*(mr-ml))); } // cout<<"ASD"<<endl; // prllf("%d",a[i]mr-ml); } printf("%lld\n",ans); // for(ll i=1;i<=n;i++){ // prllf("%d %d\n",pl[i],pr[i]); // } }

 

最新回复(0)