Alice has a magic array. She suggests that the value of a interval is equal to the sum of the values in the interval, multiplied by the smallest value in the interval.
Now she is planning to find the max value of the intervals in her array. Can you help her?
First line contains an integer n(1≤n≤5×10^5).
Second line contains nn integers represent the array a(−10^5≤ai≤10^5).
One line contains an integer represent the answer of the array.
5
1 2 3 4 5
36
区间最小值乘区间和的最大值,注意区间元素可能为负数
单调栈+RMQ,使用单调栈确定以某个元素为最小值的最大区间,然后使用ST表维护前缀和的最大、最小值。
设以编号为M的元素为最小元素向左向右能扩展到的最大区间为[L,R]
当元素大于等于0时,在区间内找一个包含此元素的最大区间
即 [M,R]的最大值 - [L-1,M-1]的最小值
当元素小于0时,在区间内找一个包含此元素的最小区间
即 [M,R]的最小值 - [L-1,M-1]的最大值
#include
#include
#include
using namespace std;
typedef long long ll;
const int N=500050;
int a[N],s[N],l[N];
ll sum[N],dpmax[N][25],dpmin[N][25];
void ST(int n)
{
for(int i=0;i<=n;i++) dpmax[i][0]=sum[i],dpmin[i][0]=sum[i];
for(int j=1;(1<0&&a[s[top]]>a[i])
{
ll temp;
int L=l[s[top]],M=s[top],R=i-1;
if(a[M]>=0)
temp=query(M,R,0)-query(L-1,M-1,1);
else
temp=query(M,R,1)-query(L-1,M-1,0);
ans=max(ans,temp*a[M]);//更新结果
l[i]=l[s[top]];
top--;
}
if(top>0&&a[s[top]]==a[i]) l[i]=l[s[top]];
s[++top]=i;
}
printf("%lld\n",ans);
}
return 0;
}