单调栈笔记

单调栈笔记

[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;
}
posted @ 2024-12-20 21:57  Qian·JXのjoker  阅读(27)  评论(0)    收藏  举报