虽然标签是单调队列优化DP。
但这道题是一道很典的前缀和+单调栈。
预处理完前缀和后分别从左往右和从右往左把每个点的最大&最小的边界条件预处理出来。
最后对所有可能线性询问一次,取最大值。
时间复杂度O(n)。
AC 代码
`#include<bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';
#define il inline
#define inf 0x3f3f3f3fusing namespace std;
using ll = long long;
using ull = unsigned long long;const int maxn = 1e5+10;int n,a[maxn],stk[maxn],top,l[maxn],r[maxn];
ll s[maxn],ans = -inf;int main(){// freopen("test.in","r",stdin);// freopen("test.out","w",stdout);ios::sync_with_stdio(0),cout.tie(0),cin.tie(0);cin>>n;for(int i = 1;i <= n;i++)cin>>a[i];for(int i = 1;i <= n;i++)s[i] = s[i-1] + a[i];// 预处理前缀和for(int i = 1;i <= n;i++)//从左往右{while(top && a[stk[top]] >= a[i])top--;l[i] = stk[top];stk[++top] = i;}top = 0;stk[0] = n+1;for(int i = n;i >= 1;i--)//从右往左{while(top && a[stk[top]] >= a[i])top--;r[i] = stk[top] - 1;stk[++top] = i;}for(int i = 1;i <= n;i++)//遍历取最大值{ans = max(ans,(s[r[i]] - s[l[i]]) * a[i]);}cout<<ans;return 0;
}