P2422 良好的感觉

原题链接

题解

1.我们没法遍历每个区间然后找出他们的最小值,所以我们考虑每个元素对答案的贡献
2.对于每一个元素来说,它的贡献等于它所在的区间长度乘上自身的值,这里的区间指的是以它为最小值的区间
3.以每个元素为最小值的区间要怎么求呢?我们将其转换成求左边第一个小和右边第一个小
对于这种问题(求序列中最近最小元素),我们建立一个栈,然后线性遍历,维护栈使其从底到顶下标有序,值也有序
如果是求左边最小值的话,我们维护栈内元素的下标成升序,值成降序。这样一来,我们可以遍历栈来找到左边第一个最小值了(有点像把升序折叠起来了?反正是个子问题)
右边同理
注意不同题细节不同,这里我们遍历找到的是第一个比i的元素,所以它们不算在内i对答案的贡献内,空栈的含义是没有比自己小的,那就赋为端点

code

#include<bits/stdc++.h>
using namespace std;
int a[100005]={0},pre[100005]={0},l[100005]={0},r[100005]={0};
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        pre[i]=pre[i-1]+a[i];
    }
    stack<int> q;
    for(int i=1;i<=n;i++)
    {
        while(q.size()&&a[q.top()]>=a[i]) q.pop();
        if(q.size()) l[i]=q.top();
        else l[i]=0;
        q.push(i);
    }

    stack<int> q2;
    for(int i=n;i>=1;i--)
    {
        while(q2.size()&&a[q2.top()]>=a[i]) q2.pop();
        if(q2.size()) r[i]=q2.top();
        else r[i]=n+1;
        q2.push(i);
    }

    int ans=0;
    for(int i=1;i<=n;i++) ans=max(ans,a[i]*(pre[r[i]-1]-pre[l[i]]));
    cout<<ans;
    return 0;
}

posted @   纯粹的  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示