单调栈笔记
单调栈笔记
[USACO06NOV] Bad Hair Day S
https://www.luogu.com.cn/problem/P2866
题目描述
农夫约翰有 \(N\) 头奶牛正在过乱头发节。
每一头牛都站在同一排面朝右,它们被从左到右依次编号为 \(1, 2, \cdots, N\)。编号为 \(i\) 的牛身高为 \(h_i\)。第 \(N\) 头牛在最前面,而第 \(1\) 头牛在最后面。
对于第 \(i\) 头牛前面的第 \(j\) 头牛,如果 \(h_i>h_{i+1}, h_i>h_{i+2}, \cdots, h_i>h_j\),那么认为第 \(i\) 头牛可以看到第 \(i+1\) 到第 \(j\) 头牛。
定义 \(C_i\) 为第 \(i\) 头牛所能看到的牛的数量。请帮助农夫约翰求出 \(C _ 1 + C _ 2 + \cdots + C _ N\)。
输入格式
输入共 \(N + 1\) 行。
第一行为一个整数 \(N\),代表牛的个数。
接下来 \(N\) 行,每行一个整数 \(a _ i\),分别代表第 \(1, 2, \cdots, N\) 头牛的身高。
输出格式
输出共一行一个整数,代表 \(C _ 1 + C _ 2 + \cdots + C _ N\)。
样例 #1
样例输入 #1
6
10
3
7
4
12
2
样例输出 #1
5
提示
数据规模与约定
对于 \(100\%\) 的数据,保证 \(1 \leq N \leq 8 \times 10 ^ 4\),\(1 \leq h _ i \leq 10 ^ 9\)。
思路
单调栈板子,保证栈顶最大,从前往后遍历,栈顶比当前小的就删掉。并在每次入栈后将栈中剩余统计入答案。
code
#include<bits/stdc++.h>
using namespace std;
const int N=8e4+5;
int n;
int st[N];
int h[N];
int cur;
int ans;
int main(){
// freopen("test.in","r",stdin);
// freopen("test.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++) cin>>h[i];
for(int i=1;i<=n;i++){
while(cur&&h[i]>=st[cur]) cur--;
// if(cur==0||h[i]>st[cur]) st[++cur]=h[i];
ans+=cur;
st[++cur]=h[i];
}
cout<<ans<<endl;
return 0;
}

浙公网安备 33010602011771号