[COI2007] Patrik 音乐会的等待 (单调栈,模拟)

题目描述

N个人正在排队进入一个音乐会。人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人。队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的。

写一个程序计算出有多少对人可以互相看见。

输入输出格式

输入格式:

输入的第一行包含一个整数N (1 ≤ N ≤ 500 000), 表示队伍中共有N个人。

接下来的N行中,每行包含一个整数,表示人的高度,以毫微米(等于10的-9次方米)为单位,每个人的调度都小于2^31毫微米。这些高度分别表示队伍中人的身高。

输出格式:

输出仅有一行,包含一个数S,表示队伍中共有S对人可以互相看见。

输入输出样例

输入样例#1:

7
2
4
1
2
2
5
1

输出样例#1:

10

Solution

直接开一个单调递减的单调栈.然后每一次碰到大的就统计答案即可.
注意处理相等的情况.

代码

#include<bits/stdc++.h>
using namespace std;
const int inf=1926081700;
const int maxn=500008;
int n,flag;
int a[maxn],ans;
stack <int>q;
int main()
{
	ios::sync_with_stdio();
	cin>>n;
	q.push(inf);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);int sum=1;
        while(a[i]>=q.top())
        {
            if(q.top()==a[i]) sum++;
            ans++;
            q.pop();
        }
        if(q.size()>1) ans++;
        while(sum--) q.push(a[i]);
    }
    //ans+=(n-1);
    cout<<ans<<endl;
}
posted @ 2018-06-19 19:48  Kevin_naticl  阅读(347)  评论(0编辑  收藏  举报