单调栈

单调栈:

什么是单调栈?

单调,顾名思义,就是单调递增或单调递减

栈,“先进后出”的STL容器

单调+栈=单调栈(手动笑哭),好理解吧?

单调栈怎么用?

我们先通过洛谷P5788 【模板】单调栈洛谷P2947这两道题(P2947就是披着背景外衣的模板题!)来真切地认识一下单调栈

  • 题目简述:
    给定n个元素Ai,要求求出数列中第i个元素之后第一个大于Ai的元素的下标

  • 注意事项:
    模板题的数据范围比P2947大,但加一个快读即可解决

  • 代码Code:

现给出【模板】的程序代码,P2947应该直接改一下【模板】的输出格式就能A掉qvq

#include <bits/stdc++.h>
using namespace std;
long long n,a[3000005],ans[3000005];

stack<long long> shan;

inline int read(){
    int x(0);
    char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) {
    	x=(x*10)+(c^48);
		c=getchar();
	}
    return x;
}

int main() {
	n=read();
	for(register int i=1;i<=n;i++) {
		a[i]=read();
	}
	for(register int i=n;i>=1;i--) { //注意理解一下倒序处理 
		while(!shan.empty()&&a[shan.top()]<=a[i]) shan.pop(); //维护栈底元素始终最大
		if(shan.empty()) { //如果栈为空就是没有,即0 
			ans[i]=0;
		}
		else ans[i]=shan.top(); //反之大于ai的第一个元素就是栈顶元素
		shan.push(i); //判断之后再入栈 
	}
	for(register int i=1;i<=n;i++) printf("%lld ",ans[i]);
	return 0;
}
  • 解释一下那个倒序处理叭:

因为我们要找的是第一个大于Ai的元素下标,且满足条件的元素一定在Ai的右边,所以我们倒序先将后面的处理出来,前面的答案也就出来了


练习题目:

(1)洛谷P2866[USACO06NOV]Bad Hair Day S 思路挺巧的

(2)洛谷P5788 【模板】单调栈

(3)洛谷P2947


原文地址:https://www.cnblogs.com/Eleven-Qian-Shan/p/13088440.html