单调栈练习题题解

这篇博客详细介绍了单调栈的概念,包括单调递增和递减栈,并通过讲解POJ3250、POJ2796、BZOJ1113、HDU1506和POJ2559等练习题,展示了如何利用单调栈解决实际问题,如求解最大矩形面积、抵消高度等。通过实例代码分析,强调了单调栈在寻找某个数左右侧第一个比它大或小元素方面的高效性,以及在处理这类问题时的时间复杂度优势。
摘要由CSDN通过智能技术生成

单调栈

单调栈顾名思义就是让栈中的元素是单调的,要么递增,要么递减。同样它也满足栈的性质,先进后出。

  • 单调递增栈,则从栈顶到栈底的元素是严格递增的
  • 单调递减栈,则从栈顶到栈底的元素是严格递减的

练习题

POJ3250

POJ3250传送门
对于每一个牛来说,能看到的数目为向右数身高比它小的个数,累加就是答案。
所以可以倒着维护一个单调递增的栈,记录i之前的弹栈数目,累加。
(正着也可以,那么就是维护对于每一头牛来说,它被多少头牛看到)
Code:

#include <stdio.h>
#define MAXN 80000+100
typedef unsigned long long llu;
llu n,ans=0;
long long s_size=-1;
llu s[MAXN];
int main()
{
    scanf("%llu",&n);
    for(llu i=1;i<=n;i++)
    {
        llu x;
        scanf("%llu",&x);
        while(s_size>=0&&x>=s[s_size])s_size--;
        s[++s_size]=x;
        ans+=s_size;
    }
    printf("%llu\n",ans);
    return 0;
}

POJ2796

POJ2796传送门 这道题比较麻烦,但是思想很重要,对于每一个点,求出向左/右第一个比它大的位置,然后O(N)枚举,找出最值。 但是需要注意两点:
开long long
预处理前缀和
Code:
#include<stdio.h>
#include<string.h>
#include<stack>
#define MAXN 100005
typedef long long ll;
using namespace std;
ll n,x,ans,l_,r_,top;
ll a[MAXN],l[MAXN],r[MAXN],s[MAXN],sum[MAXN];
ll max(ll a,ll b){
  return a>b?a:b;}
int main()
{
    while(~scanf("%lld",&n)&&n)
    {
        ans=0;
        l
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值