洛谷P1823 [COI2007]Patrik 音乐会的等待
【题意】:
N个人正在排队进入一个音乐会。人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人。对于队列中任意两个人
A和
B,如果他们是相邻的人或他们之间没有人比
A或
B高,那么他们是可以互相看得见的。
写一个程序计算出有多少对人可以互相看见。
1≤N≤5×105,人的高度以微毫米(1×10−9米)为单位记,是int范围内的正整数。
【思路】: 先考虑此问题的退化版:人的高度不能相同的情况。此时,这是一道
单调栈的模板题。
但是人的高度可以相等,这就很棘手了。因为我们在添加元素的时候,如果前面有相同的元素时,我们不知道该不该删除前面相同的元素,并且就样例而言,删除与否都会得到错误的答案。
我们在原算法的基础上给单调栈内的每一个元素新增加一个需要维护的量
Q,表示相同元素的个数。我们可以发现,如果元素高度相同且相邻,那么它们肯定一起被删除,一起被统计。明白这一点,原题就可以
AC了。
总的时间复杂度:
O(N)。主要性能瓶颈在输入和单调栈的维护。
【代码】:
【关于代码】:
- 代码中的
read()
函数即快读函数,考虑到大家都会,且限于篇幅,不再给出。
- 除代码给出的
主函数
和read()
读入函数外,本代码没有其它函数。即代码的主体已经给出。
- 代码中没有任何的反作弊系统,大家可以放心参考。
【关于时间复杂度的证明】:
- 其实本代码的时间复杂度证明的困难在于那个
while循环
,我们这样来看,因为每个元素只能被加入一次和删除一次,因为我们只加入了
N个元素,所以最多也只有
N次删除,所以总的时间复杂度也是
O(N)。
- 该方法非常常用,也非常有用,希望读者可以掌握该时间复杂度的分析方法。