单调栈

来源:互联网 发布:ov7670数据手册 编辑:程序博客网 时间:2024/04/19 20:53

维护一个有两个键值的序列, 对于每个 i, 询问一个 最小的 j , 使得h[j] >= h[i] 且 j < i。

直观的想法: 用set水。 或者rmp套一个二分。  但都慢而不优美。

更好的做法?  单调栈

单调性在哪里?

—— t > 0 则, h[i + t] < h[i]  当且仅当 j[ i + t ] >= i; h[i + t] >= h[i] 当且仅当 h[ j [ i + t ] ]  >= h[i] (像是一句废话,,)

有什么用?

考虑 有一个 沿 序号 单调递增 且 沿 h 单调递减的序列, 从序号最小到最大扫一遍, 每扫到一个点 i, 它的 j 即为从序列尾端 开始扫遇到的第一个 h >= h[i] 的数, 嗯然后把 i 加入这个 序列 (加到i 的后面), 这时候序列中在 j 之后的数 显然不会再被用到了, 都弹出即可。

哦——这就是一个栈么。时间复杂度是 O(n) 的


写起来也很容易,,


练习题

【bzoj1657】[Usaco2006 Mar]Mooo 奶牛的歌声

【bzoj1660】[Usaco2006 Nov]Bad Hair Day 乱发节

这两题 一样, 都可以用set 或者 rmq + 二分来水。


【bzoj1683】[Usaco2005 Nov]City skyline 城市地平线

【bzoj1628】[Usaco2007 Demo]City skyline

【bzoj1113】[Poi2008]海报PLA

一道题出三次也真是蛮拼的呢, 的确很巧妙, 我的题解


【bzoj1012】[JSOI2008]最大数maxnumber

这竟然不是线段树,,,哭了。



0 0
原创粉丝点击