博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷P1823 [COI2007] Patrik 音乐会的等待(单调栈+二分查找)
阅读量:5323 次
发布时间:2019-06-14

本文共 1275 字,大约阅读时间需要 4 分钟。

洛谷P1823 [COI2007] Patrik 音乐会的等待(单调栈+二分查找)

标签:题解

阅读体验:

这个题不是很难,但是没有转过来还是难想的

可以先去做一下这个题:
蒟蒻发现很多题解都是错的呀,复杂度比较玄学吧
介绍一种标准的\(O(nlogn)\)的方法

单调栈

我们对于一个人作为方案中右边那个人时我们算答案(为了不算重)

有哪些人我们看不到呢,无非是被它右边的人挡住了是吧
那么从左往右维护一个单调递减的单调栈,单调栈中的人不会出现被挡住的情况(只有\(i\)看不到的情况后面会讲)
自己想一下这里很简单

二分查找

考虑肯定只有单调栈中的人会被\(i\)算入答案是吧

并且很容易发现一定是个连续的区间\([x,i-1]\)这不废话吗
那么我们在单调栈中二分这个区间的左端点,显然左端点就是\(i\)左边第一个比\(i\)高的数
这不就是上面那个的题目了吗
计入答案的就是区间长度啦

代码极其简单。。。

#include
#define il inline#define rg register#define ldb double#define lst long long#define rgt register int#define N 500050using namespace std;const int Inf=1e9;il int read(){ int s=0,m=0;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')m=1;ch=getchar();} while( isdigit(ch))s=(s<<3)+(s<<1)+(ch^48),ch=getchar(); return m?-s:s;}int n,top;lst Ans;int H[N],stk[N];il void Calc(rgt x){ rgt le=0,ri=top,mid,ret=0; while(le<=ri) { mid=(le+ri)>>1; if(H[stk[mid]]>x)ret=mid,le=mid+1; else ri=mid-1; } if(!ret)Ans+=top; else Ans+=top-ret+1;}int main(){ n=read(); for(rgt i=1;i<=n;++i)H[i]=read(); for(rgt i=1;i<=n;++i) { Calc(H[i]); while(top>0&&H[i]>H[stk[top]])--top; stk[++top]=i; }return printf("%lld\n",Ans),0;}

转载于:https://www.cnblogs.com/cjoierljl/p/9912127.html

你可能感兴趣的文章
java.lang.OutOfMemoryError异常解决方法
查看>>
Css让文字自适应Table宽度[转]
查看>>
[Javascript] Flattening nested arrays: a little exercise in functional refactoring
查看>>
练习10-1 使用递归函数计算1到n之和(10 分
查看>>
使用maven构建多模块项目,分块开发
查看>>
Oracle MySQL yaSSL 不明细节缓冲区溢出漏洞2
查看>>
jffs2镜像制作
查看>>
windows编程ASCII问题
查看>>
.net webService代理类
查看>>
C#高级编程笔记(一)
查看>>
Code Snippet
查看>>
MFC模态对话框程序不响应OnIdle
查看>>
Node.js Express项目搭建
查看>>
zoj 1232 Adventure of Super Mario
查看>>
Oracle 序列的应用
查看>>
1201 网页基础--JavaScript(DOM)
查看>>
组合数学 UVa 11538 Chess Queen
查看>>
uva 10004 - Bicoloring
查看>>
oracle job
查看>>
Redis常用命令
查看>>