【模板】单调栈
题目背景
模板题,无背景。
2019.12.12 更新数据,放宽时限,现在不再卡常了。
题目描述
给出项数为 的整数数列 。
定义函数 代表数列中第 个元素之后第一个大于 的元素的下标,即 。若不存在,则 。
试求出 。
输入格式
第一行一个正整数 。
第二行 个正整数 。
输出格式
一行 个整数表示 的值。
样例 #1
样例输入 #1
5
1 4 2 3 5
样例输出 #1
2 5 4 5 0
提示
【数据规模与约定】
对于 的数据,;
对于 的数据, ;
对于 的数据,,。
思路
首先,定义一个数组和,以及一个栈。数组用于存储输入的数列,数组用于存储每个元素后面第一个比它大的元素的下标。
在主函数中,首先读取数列的长度,然后读取数列的每个元素,存储在数组中。然后,对于数列中的每一个元素,检查栈顶元素是否小于当前元素。如果是,则更新栈顶元素在数组中的值为当前元素的下标,并弹出栈顶元素。然后将当前元素的下标入栈。这样,栈中的元素总是保持单调递减的顺序,即栈顶元素总是栈中最小的元素。
最后,输出数组中的每一个元素,即每个元素后面第一个比它大的元素的下标。
注意 :
- 因为要找的是第 个元素之后第一个大于 的元素的下标,所以要往栈里存下标而不是元素的数值。
- 可能会出现重复数据。因为要找的是第 个元素之后第一个大于 的元素的下标,所以当
a[stk.top()] < a[i]
时出栈。如果写成a[stk.top()] <= a[i]
,会报WA,只能得60分。警钟撅烂!!!
AC代码
#include <algorithm>
#include <iostream>
#include <stack>
#define AUTHOR "HEX9CF"
using namespace std;
const int N = 1e7 + 7;
int n;
int a[N], f[N];
stack<int> stk;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
while (stk.size() && a[stk.top()] < a[i]) {
f[stk.top()] = i;
stk.pop();
}
stk.push(i);
}
for (int i = 1; i <= n; i++) {
cout << f[i] << " ";
}
return 0;
}