题解 P2422 【良好的感觉】
一道挺显然的单调栈题目。
我们可以找出这个以元素为最小值的极大区间,然后依次以每个元素为最小值更新出最优答案。
我们考虑如何找这个极大的区间,显然可以使用单调栈。
我们用单调栈求出左边第一个比当前元素
预处理和计算都是线性的,跑的比较快。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
ll a[N] , n;
ll st[N] , top;
ll L[N] , R[N];
ll sum[N];
int main () {
scanf("%lld" , &n);
for(int i = 1 ; i <= n ; i ++) scanf("%lld" , a + i);
for(int i = 1 ; i <= n ; i ++) {
while(top != 0 && a[st[top]] >= a[i]) {R[st[top]] = i;top --;}
st[++ top] = i;
}
for(int i = 1 ; i <= top ; i ++) R[st[i]] = n + 1;
top = 0;
for(int i = n ; i >= 1 ; i --) {
while(top != 0 && a[st[top]] >= a[i]) {L[st[top]] = i ; top --;}
st[++ top] = i;
}
for(int i = 1 ; i <= top ; i ++) L[st[i]] = 0;
ll ans = 0;
for(int i = 1 ; i <= n ; i ++) sum[i] = sum[i - 1] + a[i];
for(int i = 1 ; i <= n ; i ++) {
ans = max(ans , a[i] * (sum[R[i] - 1] - sum[L[i]]));
}
printf("%lld\n" , ans);
return 0;
}