P5788 模板 单调栈

【模板】单调栈

题目描述

给出项数为 \(n\) 的整数数列 \(a_{1 \dots n}\)

定义函数 \(f(i)\) 代表数列中第 \(i\) 个元素之后第一个大于 \(a_i\) 的元素的下标,即 \(f(i)=\min_{i<j\leq n, a_j > a_i} \{j\}\)。若不存在,则 \(f(i)=0\)

试求出 \(f(1\dots n)\)

输入格式

第一行一个正整数 \(n\)

第二行 \(n\) 个正整数 \(a_{1\dots n}\)

输出格式

一行 \(n\) 个整数 \(f(1\dots n)\) 的值。

样例 #1

样例输入 #1

5
1 4 2 3 5

样例输出 #1

2 5 4 5 0

提示

【数据规模与约定】

对于 \(30\%\) 的数据,\(n\leq 100\)

对于 \(60\%\) 的数据,\(n\leq 5 \times 10^3\)

对于 \(100\%\) 的数据,\(1 \le n\leq 3\times 10^6\)\(1\leq a_i\leq 10^9\)

注意 我们单调栈 单调队列存储的都是数组元素的下标 而不是数组元素的值!

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=3e6+5;
int n,a[N],f[N],st[N],pt=0;
signed main()
{
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	a[0]=LONG_LONG_MAX;
	//st[]:order not value!
	for(int i=1;i<=n;i++)
	{
		if(a[i]<a[st[pt]])st[++pt]=i;
		else
		{
			while(a[st[pt]]<a[i]&&pt>0)
			{
				f[st[pt]]=i;
				pt--;
			}
			st[++pt]=i;
		}
	}
	for(int i=1;i<=n;i++)cout<<f[i]<<" ";cout<<"\n";
	return 0;
}
posted @ 2023-04-02 10:59  N0zoM1z0  阅读(44)  评论(0编辑  收藏  举报