poj3250(单调栈模板题)

本文介绍使用单调栈解决序列中每个点右边第一个大于等于自身的点的下标问题,通过单调栈可以将复杂度从O(n^2)降低到O(n),并提供AC代码示例。

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

题目链接:https://vjudge.net/problem/POJ-3250

题意:求序列中每个点右边第一个>=自身的点的下标。

思路:简单介绍单调栈,主要用来求向左/右第一个小于/大于自身的下标,直接求的话复杂度为O(n2),而单调栈只有O(n),利用好单调栈十分有用。一个元素向左遍历的第一个比它小的数的位置就是将它插入单调栈时栈顶元素的值,若栈为空,则说明不存在这么一个数。然后将此元素的下标存入栈,就能类似迭代般地求解后面的元素

  单调栈的本质是,当一个数a在另一个数b前面且比b大,那么数a就在找第一个比某数小的问题里就完全没有考虑的必要了,他被b完全屏蔽了。

  这道题就是单调栈的简单应用,模板题。注意结果用int存不下,需要用long long。

AC代码:

#include<cstdio>
using namespace std;

int n,a[80005],stk[80005],p;
long long ans;

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
        scanf("%d",&a[i]);
    a[n+1]=0x3f3f3f3f;
    stk[p++]=n+1;
    for(int i=n;i>=1;--i){
        while(a[stk[p-1]]<a[i]) --p;
        ans+=stk[p-1]-i-1;
        stk[p++]=i;
    }
    printf("%lld\n",ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/FrankChen831X/p/10784015.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值