P2422 良好的感觉(单调栈)

这篇文章讲解了一种利用单调栈解决洛谷题目2422的良好感觉的方法。博主通过分析指出,关键在于找到每个数左右两边最近的较小值,通过单调栈实现高效查找。代码展示了如何使用栈来记录这些信息,并提供了详细的AC代码实例。
摘要由CSDN通过智能技术生成

原题链接:良好的感觉 - 洛谷

  

思路:枚举区间太复杂了,但是看看,所有区间的最小值最多有n个,那么找到这些最小值枚举最小值以及它们存在的区间就能得到答案。对于a[i]作为最小值的时候,是找它的左边最近的大于它的那个点和右边最近的并且大于它的那个点,然后区间我们就找到了。左边最近比它小、右边最近比它小--->单调栈。从前到后把a[i]的下标i入栈,如果前面有比它大的,就把栈弹出弹出..一直到栈顶的值小于等于a[i],那么这个时候的q[tail]值就是距离a[i]左边最近并小于等于a[i]的下标;同样while循环里就是找到a[q[tail]]右边最近并比其小的值。因为最后一个值进栈会有问题,那么就设一个a[n + 1]为0,就当某些值右边比它小的值了。所以入栈的时候i要从1到n + 1。细节方面还是多注意,答案记得开long long。

AC代码:

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define PII pair<int,int>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
#define rrep(i, n) for(int i = n; i >= 1; ++i)

using namespace std;

const double pi = acos(-1.0);

const int N = 1e5 + 10;
int a[N], q[N];
ll f[N], sum[N];

int main()
{
    int n;
    scanf("%d", &n);
    rep(i, n) scanf("%d", &a[i]);
    rep(i, n) sum[i] = sum[i - 1] + a[i];
    int tail = 0;
    a[n + 1] = 0;
    for(int i = 1; i <= n + 1; i++) //要到n + 1
    {
        while(a[i] < a[q[tail]]) //找到a[i]左边最近比它小的值
        {
            f[q[tail]] += sum[i - 1] - sum[q[tail]]; //q[tail]不是tail
            tail--;
        }
        f[i] = sum[i] - sum[q[tail]];
        q[++tail] = i; //记录的是下标
    }
    ll ans = -1;
    rep(i, n) ans = max(ans, 1ll * a[i] * f[i]);
    printf("%lld", ans);
    return 0;
}

 参考:题解 P2422 【良好的感觉】 - xMinh 的博客 - 洛谷博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值