ABC372D ABC379F 题解 单调栈二分

ABC372D ABC379F 题解 单调栈二分

一直觉得AT上面学到的东西比CF要多一些,无意捧一踩一,但可能是我太菜的原因,毕竟ABC的题目普遍要比Div.2 简单一些。

好多次碰到这个单调栈里面二分的 trick 了,所以写一篇来总结一下。

ABC 372 D

形象地给定一系列 Buildings 的高度 h ,保证每个 h 不相等。

问一共有多少对 (i,j) 满足 i<j 并且其间不存在比 j 高的建筑。

我们考虑对于一个 j ,如果它之前存在一个比它高的建筑 j ,那么对于所有 j 之前的 i ,其都不能和 j 构成一个合法的对,那么这个 j 对于所有这样的 i 都是可以不用考虑的。

维护

那么这样的话我们其实就可以倒序枚举 i ,然后维护一个从顶到底单调递增的单调栈,被弹出的元素一定对现在以及之后所有的 i 不会有贡献了,所以可以直接弹出。

统计答案

每个答案实际上就是当前栈里的元素个数。

后话

貌似这个版本是不用再单调栈上面二分的,然而我当时如同一个 2b ,不仅使用了二分,甚至还用了差分和前缀和来统计每一个固定的 ji 的贡献,而不是直接计算 i 的答案。

不过这也倒是间接为我在这个强化版问题上面提供了思路,导致想起来没有什么困难。

ABC 379 F

这个就是给定若干个 (li,ri) ,问在 ri 的右边有多少建筑能够被 liri 处的建筑同时看到。

分析

不难发现,满足答案的建筑所必须满足的必要条件是能够被 li 看到,当其序号满足在 ri 右边的时候,这就变成了一个充要条件了。

所以我们直接离线,然后按左端点从小到大排序,然后倒序枚举区间,把所有 li 之后序号的放进单调栈里面,之后再二分找所有序号大于 ri 的即可

维护

不难发现,我们即使不弹出,单调栈里面元素对应的序号也一定是单调的,所以单调栈里可以直接存序号,我们在维护的时候通过序号访问高度,在查询的时候直接查询序号即可。

Code

posted @   Hanggoash  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
动态线条
动态线条end
点击右上角即可分享
微信分享提示