[bzoj1657][Usaco2006 Mar]Mooo 奶牛的歌声(单调栈)

本文介绍了一种使用单调栈解决特定问题的方法。通过维护一个单调递增或递减的栈,可以高效地找到每个元素左侧和右侧最近的比它高或低的元素。这种技巧对于求解诸如视线遮挡等问题非常有用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

我是超链接

题解:

博主发现自己对单调栈一无所知?
看来是个板子了,作为一头牛可以听到左右两边身高不高于ta的声音
记录一下自己声音可以越过的最远左右端点l,r,那么l-1,r+1的牛可以听到ta

说一下单调栈?
由于每一个点的左右端点都只会被左边/右边第一个大于/小于它的点来更新,那么可以维护一个单增/单减的栈,从前向后和从后向前分别扫一遍,每一次更新右端点或者左端点。
单调栈常见的用途是维护以每一个点为最大值/最小值的最长的区间是多少。

代码:

#include <cstdio>
#include <iostream>
#define N 50005
using namespace std;
int h[N],val[N],l[N],r[N],stack[N],sum[N];
int main()
{
    int n,i,top=0;
    scanf("%d",&n);
    for (i=1;i<=n;i++)
      scanf("%d%d",&h[i],&val[i]),l[i]=1,r[i]=n;
    for (i=1;i<=n;i++)
    {
        while (top&&h[stack[top]]<h[i])
        {
            r[stack[top]]=i-1;
            top--;
        }
        stack[++top]=i;
    }
    top=0;
    for (i=n;i>=1;i--)
    {
        while (top&&h[stack[top]]<h[i])
        {
            l[stack[top]]=i+1;
            top--;
        }
        stack[++top]=i;
    }
    int ans=0;
    for (i=1;i<=n;i++) sum[l[i]-1]+=val[i],sum[r[i]+1]+=val[i];
    for (i=1;i<=n;i++) ans=max(ans,sum[i]);
    printf("%d",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值