[笔记]单调栈

原题链

单调栈,顾名思义就是存储在栈中的元素是具有单调性的(单调递增或单调递减),根据不同的要求进行维护

来看看洛谷的板子题.题目要求找第一个比当前数大的数的序号.

一开始我手推了一下,发现了如何实现单调栈,拿样例来看:栈里面先\(push\)进去\(1\),接着读取到了\(4\),发现它比栈顶元素大,就弹出\(1\),加入\(4\),而1对应的答案也就是\(4\),下标为\(2\).接着读取的是\(2,3\),这两个数放入栈中不会破坏单调性,直到读取到\(5\),它比栈里面所有的元素都打,所以栈里面所有元素的答案都是\(5\),栈被清空,栈中加入\(5\),而此时\(5\)是最后一个元素,所以它的答案是\(0\).

这样基本的思路就出来了.在实现的时候我一开始遇到了问题,我最初写的是直接用栈来维护序列的数值,再用一个\(map\)来映射标号,记录答案,但由于\(STL\)等奇奇怪怪的原因导致了\(TLE\).看过题解后我发现其实可以直接用栈来维护下标,在判断的时候将栈内元素作为下标来比较即可,还是我太菜了~~

总体而言,单调栈还是比较简单,只是根据问题的不同会有变化,只做模板题是肯定不够的,还要在以后的练习中灵活变通

代码如下

#include <bits/stdc++.h>
using namespace std;
stack < int > s;
long long a[3000010];
long long ans[3000010];
int main(){
	int n;
	scanf("%d",&n);
	for(int i = 1;i <= n;i++){
		scanf("%lld",&a[i]);
	}
	s.push(1);
	for(int i = 2;i <= n;i++){
		while(!s.empty() && a[i] > a[s.top()]){
			ans[s.top()] = i;
			s.pop();
		}
		s.push(i);
	}
	for(int i = 1;i < n;i++){
		printf("%lld ",ans[i]);
	}
	printf("0\n");
	return 0;
}
posted @ 2020-10-22 21:23  czyczy  阅读(130)  评论(0编辑  收藏  举报