https://ac.nowcoder.com/acm/contest/884/C
要用线段树(
4
∗
m
a
x
n
4*maxn
4∗maxn空间),不能用RMQ(
m
a
x
n
∗
l
o
g
(
m
a
x
n
)
maxn*log(maxn)
maxn∗log(maxn)空间),否则MLE。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=3e6+100;
int n,a[maxn],b[maxn],pl[maxn],pr[maxn];
ll sum[maxn],ans=-1e9;
ll maxv[maxn*4],minv[maxn*4];
void build(int o,int l,int r)
{
if(l==r)minv[o]=maxv[o]=sum[l];
else
{
int m=(l+r)/2;
build(o*2,l,m);
build(o*2+1,m+1,r);
maxv[o]=max(maxv[o*2],maxv[o*2+1]);
minv[o]=min(minv[o*2],minv[o*2+1]);
}
}
ll Max(int le,int rt,int o=1,int l=0,int r=n)
{
ll maxx=-1e18;
if(le<=l&&rt>=r)return maxv[o];
else
{
int m=(l+r)/2;
if(le<=m)maxx=max(Max(le,rt,o*2,l,m),maxx);
if(rt>m)maxx=max(Max(le,rt,o*2+1,m+1,r),maxx);
return maxx;
}
}
ll Min(int le,int rt,int o=1,int l=0,int r=n)
{
ll minn=1e18;
if(le<=l&&rt>=r)return minv[o];
else
{
int m=(l+r)/2;
if(le<=m)minn=min(Min(le,rt,o*2,l,m),minn);
if(rt>m)minn=min(Min(le,rt,o*2+1,m+1,r),minn);
return minn;
}
}
int main()
{
//freopen("input.in","r",stdin);
cin>>n;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
a[0]=a[n+1]=-1e9;
for(int i=1;i<=n;i++)scanf("%d",&b[i]),sum[i]=sum[i-1]+b[i];
stack<int> s;
s.push(0);
for(int i=1;i<=n;i++)
{
while(!s.empty() && a[s.top()]>=a[i])s.pop();
pl[i]=s.top();
s.push(i);
}
while(s.empty()==0)s.pop();
s.push(n+1);
for(int i=n;i>=1;i--)
{
while(!s.empty() && a[s.top()]>=a[i])s.pop();
pr[i]=s.top();
s.push(i);
}
build(1,0,n);
for(int i=1;i<=n;i++)
{
if(a[i]==0)ans=max(ans,0LL);
else if(a[i]>0)
{
ll l=sum[i]-Min(pl[i],i-1),r=Max(i,pr[i]-1)-sum[i];
ans=max(ans,a[i]*(l+r));
}
else
{
ll l=sum[i]-Max(pl[i],i-1),r=Min(i,pr[i]-1)-sum[i];
ans=max(ans,a[i]*(l+r));
}
}
cout<<ans<<endl;
return 0;
}