单调栈排队
Posted SSL_ZZL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单调栈排队相关的知识,希望对你有一定的参考价值。
Description
n个人排成一条直线(一排),给出队伍中每个人的身高,每个人只能看到站在他右边且个头比他小没有被其他人挡住(跟他身高相同也会挡出他)的人。请求出所有人可以看到的人数之和。
1<=N<=80,000
Sample Input
6
5
10
3
7
4
12
2
Sample Output
5
解题思路
递减单调栈
计算答案,找到当前
i
i
i的右边的墙,用下标互减
code
#include<iostream>
#include<cstdio>
using namespace std;
long long n,top,a[80100],f[80100],ans;
int main()
scanf("%lld",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
a[n+1]=0x3f3f3f3f;//建右边的墙
f[++top]=n+1;
for(int i=n;i>0;i--)//从右往左找
while((top)&&(a[f[top]]<a[i]))top--;//如果右边比它矮的,那么就不会对更左边的木板产生墙贡献,出栈
ans+=f[top]-i-1;//下标互减计算答案
f[++top]=i;//压入栈
printf("%lld",ans);
以上是关于单调栈排队的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 1660 [Usaco2006 Nov]Bad Hair Day 乱发节:单调栈
LeetCode 907 子数组的最小值之和[单调栈] HERODING的LeetCode之路
CodeForces - 817D Imbalanced Array(单调栈)