单调栈就是使栈内元素单调递增或者单调递减的栈,单调栈也只能在栈顶操作。 做一个比喻,比方说:有个集训队招人,一个数代表了一个选手的能力值,先进来的选手年龄会比较大,后面的选手年龄比较小,但是这个集训队没有人数限制,那么如果遇到一个比你小还比你强的人那么准备退役吧。 比如有 5 个能力值分别是: 1 7 5 6 3 首先是 1 也就是 选手1 ,那么集训队没有人和他比较所以进入集训队。 单调栈的情况:1
然后是 7 也就是 选手2 ,那么我们可以发现,选手2 比 选手1 要小,并且 选手 2 的能力比 选手1 要强,那么 选手1 留着也没啥用,删掉。 单调栈的情况:7
然后是 5 选手3 ,选手3 比 选手2 年龄要小,但是 选手3 的能力没有 选手2 强,那么 选手3 招进集训队。 单调栈的情况:7 5
那么接下来是 6 选手4 ,选手4 比 选手3 年龄要小,比他还要强, 选手3 淘汰!往后比较,发现 选手2 虽然比 选手4 要大,但是他能力很强!所以不会被淘汰,将 选手4 招进集训队。 单调栈的情况:7 6
最后是 3 选手5 ,选手5 比 选手4 要小,但是 选手4 的能力比 选手5 要强,所以 选手4 必定也比不过 选手2 ,但由于 选手5 小所以不淘汰他。 单调栈的情况:7 6 3
刚刚解析完了单调栈,那么,现在开始分析一下这道题目吧! 这道题目就是说往右边看,找出第一个(能力)大于你的数(选手)。 不妨把它反过来,从最后一个开始入单调栈。 如果说没有比它小的那么就是输出 0 。
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef pair<int ,int >P;
stack<P>s;
int n,ans[3000010],a[3000010];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
while(!s.empty()&&s.top().first<a[i]){
ans[s.top().second]=i;
s.pop();
}
s.push({a[i],i});
}
for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
}
标签:集训队,那么,int,能力,选手,模板,单调
From: https://www.cnblogs.com/mengxiaolong/p/18372469