洛谷 P5788 【模板】单调栈
题目背景
模板题,无背景。
2019.12.12 更新数据,放宽时限,现在不再卡常了。
题目描述
给出项数为 n 的整数数列 a1…n。
定义函数 f(i) 代表数列中第 i 个元素之后第一个大于 ai 的元素的下标,即 f(i)=mini<j≤n,aj>ai{j}。若不存在,则 f(i)=0。
试求出 f(1…n)。
输入格式
第一行一个正整数 n。
第二行 n 个正整数 a1…n。
输出格式
一行 n 个整数表示 f(1),f(2),…,f(n) 的值。
输入输出样例
输入 #1复制
5 1 4 2 3 5
输出 #1复制
2 5 4 5 0
说明/提示
【数据规模与约定】
对于 30% 的数据,n≤100;
对于 60% 的数据,n≤5×103 ;
对于 100% 的数据,1≤n≤3×106,1≤ai≤109。
解题思路
这道题是单调栈的模板题,在这道题之后我也写过其他单调栈的题目,基本无差。
首先定义一个栈,将原数组逆序判断,因为我们要比较i位置后面的数据。
当栈不为空且栈最顶端数据小于数组当前的数据时,将此时栈的数据踢出。
如果栈是空的,那么直接按题目要求输入0,存入新数组中;如果不为空,那么就将此时栈中最顶端的下标存入所求新数组中。
每次循环都要将此次循环的下标存入栈中。
最后直接输出所求的数组即可,完整代码如下:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int p[10000005],arr[10000005],f[10000005];
signed main()
{int n;cin>>n;stack<int>q;for(int i=1;i<=n;i++){cin>>arr[i];}for(int i=n;i>0;i--){while(!q.empty()&&arr[q.top()]<=arr[i]){q.pop();}if(q.empty()){f[i]=0;}else{f[i]=q.top();}q.push(i);}for(int i=1;i<=n;i++){cout<<f[i]<<" ";}return 0;
}