洛谷 P1053 音乐会的等待 解题报告
Posted ppprseter
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 P1053 音乐会的等待 解题报告相关的知识,希望对你有一定的参考价值。
P1823 音乐会的等待
题目描述
\(N\)个人正在排队进入一个音乐会。人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人。队列中任意两个人\(A\)和\(B\),如果他们是相邻或他们之间没有人比\(A\)或\(B\)高,那么他们是可以互相看得见的。
写一个程序计算出有多少对人可以互相看见。
输入输出格式
输入格式:
输入的第一行包含一个整数\(N (1 ≤ N ≤ 500 000)\), 表示队伍中共有\(N\)个人。
接下来的\(N\)行中,每行包含一个整数,表示人的高度,以毫微米(等于\(10^{-9}\)次方米)为单位,每个人的调度都小于\(2^{31}\)毫微米。这些高度分别表示队伍中人的身高。
输出格式:
输出仅有一行,包含一个数\(S\),表示队伍中共有\(S\)对人可以互相看见。
很明显的单调栈。
维护一个非严格递减的序列,弹一次加一次\(ans\)即可。
有两个点:
- 关于身高相等的人的处理
我用额外的cnt记录了每个身高的人的出现次数,在弹出时加上次数即可
但要注意,在处理相邻的时候,千万不要加上cnt了,最开始因为这个只有25分。
2.开 \(long\) \(long\)
code:
#include <cstdio>
#define ll long long
const ll N=500010;
ll a,ans=0,top=0,n;
struct node
{
ll cnt,h;
}s[N];
void pop() {top--;}
void push(node t) {s[++top]=t;}
int main()
{
scanf("%lld",&n);
node t;
for(ll i=1;i<=n;i++)
{
scanf("%lld",&a);
t.cnt=1;
t.h=a;
while(top&&s[top].h<=a)
{
if(s[top].h==a) t.cnt+=s[top].cnt;
ans+=s[top].cnt;
pop();
}
if(top) ans+=1;
push(t);
}
printf("%lld\n",ans);
return 0;
}
2018.5.19
以上是关于洛谷 P1053 音乐会的等待 解题报告的主要内容,如果未能解决你的问题,请参考以下文章