The Preliminary Contest for ICPC China Nanchang National Invitational I、Max answer【单调栈+前缀和+RMQ】

The Preliminary Contest for ICPC China Nanchang National Invitational

I、Max answer

 

  •  3000ms
  •  262144K

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?

Input

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).

Output

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]的最大值 

C++代码

#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;
}

 

你可能感兴趣的:(数据结构)