标签:+= bsp cstring lin 音乐会 type 情况下 new 合并
N个人正在排队进入一个音乐会。人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人。
队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的。
写一个程序计算出有多少对人可以互相看见。
我们发现,其实就是算每个人向前看能看到多少个人之和对吧?
发现如果1号既比2号,又比2号靠后,后面的人就不可能看得到2号
于是我们考虑维护一个单调递减的栈,在不含重复大小元素的情况下,发现弹出的元素的数目就可以直接累加进ans里,特判一下如果这个时候还有元素在栈里那么显然也是看得到的,ans++
但是怎么处理重复的元素呢?我们考虑把重复的元素合并起来一起处理,具体实现就是开个pair,first记录高度,second记录人数
luogu上别忘了开long long
#include<algorithm> #include<cstring> #include<cstdio> #include<iostream> typedef long long ll; using std::pair; const int N=5e5+15; int n,r; ll ans; ll a[N]; pair <int,int> q[N]; inline ll read() { char ch=getchar(); ll s=0,f=1; while (ch<‘0‘||ch>‘9‘) {if (ch==‘-‘) f=-1;ch=getchar();} while (ch>=‘0‘&&ch<=‘9‘) {s=(s<<3)+(s<<1)+ch-‘0‘;ch=getchar();} return s*f; } int main() { n=read(); for (int i=1;i<=n;i++) a[i]=read(); for (int i=1;i<=n;i++) { pair <int,int> p(a[i],1); while (r&&q[r].first<=a[i]) { ans+=q[r].second; if (q[r].first==a[i]) p.second+=q[r].second; r--; } if (r) ans++; q[++r]=p; } printf("%lld\n",ans); return 0; }
[COI2007] [luogu P1823] Patrik 音乐会的等待 解题报告 (单调栈)
标签:+= bsp cstring lin 音乐会 type 情况下 new 合并
原文地址:https://www.cnblogs.com/xxzh/p/9680936.html