单调栈:
什么是单调栈?
单调,顾名思义,就是单调递增或单调递减
栈,“先进后出”的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 思路挺巧的
(3)洛谷P2947