题解:P2422 良好的感觉

虽然标签是单调队列优化DP。
但这道题是一道很典的前缀和+单调栈。
预处理完前缀和后分别从左往右和从右往左把每个点的最大&最小的边界条件预处理出来。
最后对所有可能线性询问一次,取最大值。
时间复杂度O(n)。

AC 代码

`#include<bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';
#define il inline
#define inf 0x3f3f3f3f

using 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;
}
posted @ 2025-03-01 15:11  Zheng_iii  阅读(12)  评论(0)    收藏  举报