应@张子渝需求,现更新一篇单调栈和单调队列。(本篇只讲单调队列)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
所谓单调就是指元素按递增或递减的排列方式规整地排列。
例如
> {1,2,3,4,5,61,2,3,4,5,61,2,3,4,5,6},
> {1,2,5,10,12,161,2,5,10,12,161,2,5,10,12,16},
> {9,8,7,6,1,−19,8,7,6,1,-19,8,7,6,1,−1}...
都属于按单调排列,而
> {1,2,7,4,5,61,2,7,4,5,61,2,7,4,5,6},
> {1,0,5,11,12,161,0,5,11,12,161,0,5,11,12,16},
> {9,8,17,6,1,−19,8,17,6,1,-19,8,17,6,1,−1}...
则不属于按单调排列。
单调队列
何为单调队列?顾名思义,单调队列即满足单调性的队列结构。为了方便描述,接下来以从队首到队尾满足递增的单调队列(即单调递增队列)举例。
现有一个单调队列,里面没有任何元素。
然后我把元素 333 加入队列,因为 {333} 符合递增关系,所以可以直接加入队列。
接着再把元素 555 加入队列,因为 {3,53,53,5} 仍符合递增关系,所以依旧可以直接加入队列。
可当如果我还要把元素 444 加入队列,因为 {3,5,43,5,43,5,4} 不符合递增关系,那么就不可以直接加入队列。为保证队列的单调性,需先把元素 {3,53,53,5} 依次弹出,再把元素 444 加入队列。
另外如果我们要弹出元素,考虑到同单调栈一样无论怎么弹,队列始终保持单调性(此处读者可自行理解),所以可直接弹出。
综上所述,单调队列基本代码应是这样的:
1.例题 求区间所有后缀最大值的位置
题目入口
该题是模板,今后注意到像“区间极值”一类的问题,可以考虑到单调队列。
该题 AC 代码如下:
此处细心的读者可能已经发现我单调队列用的 STL 是 deque,不是 queue,那么我就借此篇讲讲 deque(双端队列),也顺便给那个讲 map 加精的人找个工作@MuktorFM。
DEQUE 浅讲
deque(双端队列),支持两端进行操作,可近似地认为它就是 stack(栈)和 queue(队列)的结合体。
一些常用操作如下表(此处 qqq 即一个双端队列):
代码 含义 q.push_front(x) 在队首加入一个元素 xxx q.push_back(x) 在队尾加入一个元素 xxx q.pop_front() 在队首弹出一个元素 q.pop_back() 在队尾弹出一个元素 q.clear() 清空队列 q.emtpy() 返回队列是否为空 q.size() 返回队列大小 q.front() 返回队首元素 q.size() 返回队尾元素
其他例题(无代码,如有必要可私信,但不保证一定有讲解)
P1638 P1886 P2952 P8661 P7795
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
注:碍于ACGO题库中单调队列题太少,故上述题目均来自洛谷。并非贬低ACGO,在此对广大狗友以表歉意。另外如果需要,在下可以在ACGO上提供些单调栈的题或厚着脸皮在你谷上要版权把题目拉过来(第二种方式较困难)。