关于本题,这里只是基础的写法,完美的避开了特殊情况,另一篇博文会详细讲解特殊情况

[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
说句实话,这道题真的挺坑的,首先,我们先来说一下大体的思路。
这道题其实就是给出一个队伍,要找出所有能相互看见的一对(两个人之间没有比两个人任意一个人高的人),那么我们该怎么做呢?
我们来想一下,由于题中让我们找的是对数,为了避免找重了,我们只能看一个方向(如果你偏要看两个方向再除以二也没有人拦你。。。),但是从左往右看显然前面元素会受到后面的影响,为了保证正序判断,这里应该从右往左看。
我们任意取一位人,那么这个人所能看到最远的人就是它前面第一个比他高的人,并且如果这个人高于他左边的人P,那么显然他右边的人一定看不到P。
根据这两条性质,我们很容易想到一种数据结构:栈。又因为每个人入栈时栈中元素一定是单调不递增的,所以该栈具有单调性,因此我们引入一个新的概念:单调栈。
归概来说,每当我们放入一个元素,我们只需要执行两个操作:
1.查找第一个比他高的人,统计看到的人数
2.弹出会被他遮到(小于他)的元素
第一条我们可以用二分法查找,而第二条直接线性搜索即可。
最后,附上本题代码:
 1 #include<cstdio>
 2 using namespace std;
 3 int n,top;
 4 long long Ans;
 5 int a[500050],stk[500050];
 6 void dfs(int x)
 7 {
 8     int le=0,ri=top,mid,ret=0;
 9     while(le<=ri)
10     {
11         mid=(le+ri)>>1;
12         if(a[stk[mid]]>x)ret=mid,le=mid+1;
13         else ri=mid-1;
14     }
15     if(!ret)Ans+=top;
16     else Ans+=top-ret+1;
17 }
18 int main()
19 {
20     scanf("%d",&n);
21     for(int i=1; i<=n; ++i)scanf("%d",&a[i]);
22     for(int i=1; i<=n; ++i)
23     {
24         dfs(a[i]);
25         while(top>0&&a[i]>a[stk[top]])--top;
26         stk[++top]=i;
27     }
28     printf("%lld",Ans);
29     return 0;
30 }

转载于:https://www.cnblogs.com/yufenglin/p/10306366.html

音乐会的等待-单调栈相关推荐

  1. P1823 [COI2007] Patrik 音乐会的等待 单调栈

    单调栈 链接 栈底维护的是目前身高最高的人,因为在此人前的人因为此人的存在不能与后来的人联系了,所以如果遇到身高高的人就不断让比他身高矮的人出栈即可.不过我们还要留意身高相同的情况. 由于要考虑重复的 ...

  2. P1823 [COI2007] Patrik 音乐会的等待(单调栈)

    维护一个单调栈,使得栈顶元素最小,比如:a[1]=6,a[2]=5,a[3]=2,a[4]=6 此时 a[1],a[2],a[3] 逐步进栈,有两对可以交谈 a[4] 进栈时,可以与 a[1] 交谈, ...

  3. ACM入门之【单调栈】

    何为单调栈,顾名思义,单调栈即满足单调性的栈结构. 单调栈解决的问题: 可以找到对于当前位置左边(或右边)最近的大于(或小于)它的值(或者下标). 常用模板: typedef long long in ...

  4. Luogu P1823 [COI2007] Patrik 音乐会的等待

    Luogu P1823 [COI2007] Patrik 音乐会的等待 做一套初赛模拟题,填程序是这个 就顺便找原题做一下 :单调栈 #include<cstdio> #include&l ...

  5. P1823 [COI2007] Patrik 音乐会的等待

    P1823 [COI2007] Patrik 音乐会的等待 模型总结 单调栈 关键点 开longlong 注意对相同元素的处理,注意最劣复杂度要正确 使用二分进行统计和出栈 // from [hzwe ...

  6. 【题解】洛谷P1823 [COI2007]Patrik音乐会的等待

    前往:我自己搭建的博客 题目 洛谷P1823[COI2007]Patrik音乐会的等待 题解 使用单调栈维护一个不严格递减的数列,将新的元素与栈顶元素依次比较,如果符合要求(能互相看到)就计数,同时维 ...

  7. leetcode 739. 每日温度 单调栈解法和暴力法及其优化 c代码

    如题: 根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数.如果之后都不会升高, 请在该位置用 0 来代替.例如,给定一个列表 temperature ...

  8. 单调栈 leetcode整理(二)

    目录 为什么单调栈的时间复杂度是O(n) 496. 下一个更大元素 I 方法一:暴力 方法二:单调栈+哈希表 739. 每日温度 单调栈模版解 优化 503. 下一个更大元素 II 单调栈+循环遍历 ...

  9. [Leedcode][JAVA][第739题][每日温度][暴力][单调栈]

    [问题描述][中等] 根据每日 气温 列表,请重新生成一个列表,对应位置的输出是需要再等待多久温度才会升高超过该日的天数.如果之后都不会升高,请在该位置用 0 来代替.例如,给定一个列表 temper ...

最新文章

  1. Linux进程间的通信----->共享内存
  2. 《mysql性能调优与架构设计》笔记: 一mysql 架构组成
  3. 《PLACEBO》(安慰剂)米津玄師/野田洋次郎 (罗马音、歌词、汉译)
  4. 一份对过去120年奥运数据的可视化分析报告
  5. springboot data.redis.RedisConnectionFactory 集成问题
  6. Yammer Metrics,一种监视应用程序的新方法
  7. 软通动力华为java机考题库_华为机考笔试刷题-java-1
  8. 百度 合肥地区 软件研发工程师 笔试题
  9. Vue + OpenLayers 配置多个地图数据源
  10. 如何快速去除PDF的密码和限制:遇到PDF被加密,不能复制、编辑,怎么办?教大家一个又快又好用的方法、实用。
  11. JavaWeb技术内幕二:Java IO工作机制
  12. 互联网+废品回收项目可行性分析报告
  13. 【软件应用】福昕pdf阅读器回退到上次阅读的位置
  14. vps网速取决于什么
  15. iphone阅读模式翻页_iPad的safari浏览器阅读模式如何翻页
  16. 复旦陈果老师关于孤独、寂寞、朋友和人际的课堂笔记
  17. oracle报错——字符集不匹配
  18. MyBatis框架快速入门
  19. nike air max 1 leopard internationaal meest
  20. PHP中的addslashes双胞胎兄弟函数

热门文章

  1. 【源资讯 第37期】一个时代的终结 —— 再见, Flash !
  2. 批量去除歌曲tag标签
  3. VMware虚拟网络相关知识
  4. 监测SQLServer数据库中表的数据变化 方案
  5. POJ 1733 Parity game(带权并查集)
  6. C#_Math函数总结
  7. JSTL fn:split()函数
  8. linux su和sudo命令的区别(转)
  9. 转载:sql2005 管道的另一端上无任何进程解决方法
  10. 在/proc/devices中只能看见一个,请问是什么原因