第四场C:Sequence
https://ac.nowcoder.com/acm/contest/884/C
线段树维护区间最值,单调栈维护每个数影响的最大区间
*
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct tree
{
ll l,r,minn,maxn;
} t[3000100*5];
struct node
{
ll num,l,r;
} a[3000100];
ll b[3000100];
void build(int rt,int l,int r)
{
t[rt].l=l;
t[rt].r=r;
if(l==r)
{
t[rt].minn=b[l],t[rt].maxn=b[l];
return ;
}
int mid=(l+r)/2;
build(rt*2,l,mid);
build(rt*2+1,mid+1,r);
t[rt].maxn=max(t[rt*2].maxn,t[rt*2+1].maxn);
t[rt].minn=min(t[rt*2].minn,t[rt*2+1].minn);
}
ll querymax(int rt,int x,int y)
{
if(x<=t[rt].l&&y>=t[rt].r)
{
return t[rt].maxn;
}
else
{
int mid=(t[rt].l+t[rt].r)/2;
ll ans1=-1e10,ans2=-1e10;
if(x<=mid)
{
ans1 = querymax(rt*2,x,y);
}
if(y>mid)
{
ans2 = querymax(rt*2+1,x,y);
}
return max(ans1,ans2);
}
}
ll querymin(int rt,int x,int y)
{
if(x<=t[rt].l&&y>=t[rt].r)
{
return t[rt].minn;
}
else
{
int mid=(t[rt].l+t[rt].r)/2;
ll ans1=1e10,ans2=1e10;
if(x<=mid)
{
ans1 = querymin(rt*2,x,y);
}
if(y>mid)
{
ans2 = querymin(rt*2+1,x,y);
}
return min(ans1,ans2);
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=1; i<=n; i++)
scanf("%lld",&a[i].num);
for(int i=1; i<=n; i++)
scanf("%lld",&b[i]),b[i]+=b[i-1];
a[n+1].num=-1e7;
a[0].num=-1e7;
stack<int>stk;
for(int i=1; i<=n+1; i++)
{
while(!stk.empty()&&a[stk.top()].num>a[i].num)
{
int top=stk.top();
stk.pop();
a[top].r=i-1;
}
stk.push(i);
}
while(!stk.empty())
stk.pop();
for(int i=n; i>=0; i--)
{
while(!stk.empty()&&a[stk.top()].num>a[i].num)
{
int top=stk.top();
stk.pop();
a[top].l=i+1;
}
stk.push(i);
}
build(1,1,n);
ll ans=0;
for(int i=1; i<=n; i++)
{
if(a[i].num<0)
{
ll minn=querymin(1,i,a[i].r);
ll maxn=querymax(1,a[i].l-1,i-1);
// printf("%d-%d\n",minn,maxn);
ans=max(ans,(minn-maxn)*a[i].num);
}
else if(a[i].num>0)
{
ll minn=querymin(1,a[i].l-1,i-1);
ll maxn=querymax(1,i,a[i].r);
// printf("%d+%d\n",minn,maxn);
ans=max(ans,(maxn-minn)*a[i].num);
// ans=max(ans,(b[a[i].r]-b[a[i].l-1])*a[i].num);
}
}printf("%lld\n",ans);
}
}