单调栈
没什么东西,贴题
https://www.luogu.com.cn/problem/P5788
可以看到数据范围来到了106,n2暴力首先被pass
正解:单调栈
线性数据结构,思想很简单,从一段开始扫,对于这个题,从右往左,第一个先入栈
来到第二个,有两种情况,(1)第一个<第二个 (2)第一个>第二个(相等随便并入一个)
对于(1),很明显从此以后“第一个”不会成为答案,因为第二个要比第一个大,而后面再找最大值时,第二个肯定会被扫到,所以第一个没有必要留下了,弹栈
此时是特例,栈空了,但如果推广到其他情况,此时比当前数小的已经全部被弹了,因此栈首就是答案,但此时空了,所以第二个数的答案是0
对于(2),我们发现第一个就是答案,所以直接保存
由此可以得出程序思路:每到一个数,先拿它依次跟栈首对比,比它小就弹出,直到留下比它大的,这就是答案,然后入栈,以此类推
因为每次弹栈过后,栈都相当于被整理,于是栈内便是单调有序的
代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#define MAXN 3000050
using namespace std;
int n,f[MAXN],ans[MAXN];
struct Node{
int num,id;
}a[MAXN];
stack<Node> s;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].num;
a[i].id=i;
}
ans[n]=0;
s.push(a[n]);
for(int i=n-1;i>=1;i--){
while(!s.empty()&&a[i].num>=s.top().num){
s.pop();
}
if(s.empty()){
ans[i]=0;
}else{
ans[i]=s.top().id;
}
s.push(a[i]);
}
for(int i=1;i<=n;i++) cout<<ans[i]<<' ';
return 0;
}
注意坑,while弹栈的时候要加上是否栈空的判断,否则栈空时取top在评测时会RE

浙公网安备 33010602011771号