洛谷 P1053 音樂會的等待 解題報告
阿新 • • 發佈:2018-05-19
print () == 音樂 記錄 的人 can HR 音樂會
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 音樂會的等待 解題報告