题意:
求一段区间内的最大连续和,且该段区间的值要大于等于这段区间的最小值,并和 = 最小值*区间长度;
解题思路:
利用单调栈可求.
#define MAXN0 100011
typedef __int64 LL;
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int n;
LL h[MAXN0];
struct node{
int L,R;
void set(int aa,int bb){
L = aa ;
R = bb ;
}
void setL(int aa){
L = aa;
}
void setR(int aa){
R = aa;
}
};
node no[MAXN0];
int sk[MAXN0];
LL solve(){
LL ans = 0;
int top = 0;
sk[++top] = 1;
for(int i=2;i<=n;++i){
while(top&&h[sk[top]]>h[i]){
int tmp0 = sk[top];
top--;
no[i].setL(no[tmp0].L);
if(top>0){
no[sk[top]].setR(no[tmp0].R);
}
}
sk[++top] = i;
}
if(top>0){
int tmp0 = sk[top];
top--;
while(top>0){
no[sk[top]].setR(no[tmp0].R);
tmp0 = sk[top];
top--;
}
}
for(int i=1;i<=n;++i){
LL tmp0 = ((LL)(no[i].R - no[i].L+1))*(h[i]);
if(ans<tmp0){
ans = tmp0;
}
}
return ans;
}
int main(){
while(scanf("%d",&n)!=EOF){
if(!n)break;
for(int i=1;i<=n;++i){
scanf("%I64d",&h[i]);
no[i].set(i, i);
}
LL ans = solve();
printf("%I64d\n",ans);
}
return 0;
}