所谓单调队列,就是支持从队尾插入删除,队头查询的一种数据结构,虽然用途不是很广泛,但是对于某些问题如:在一个被不断刷新的缓存区中多次查询最小值(最大值)非常高效
构造方法:对于单调上升队列:每次从队尾入队一个元素,都从队尾起依次删除比当前元素大的元素,强制使队列单调
示例,POJ 2823 Sliding Window
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
#include<cstdio> #include<iostream>
#define MAXN 1000005 #define MAX_INT 2147483647
using namespace std;
int que_min[MAXN][2],que_max[MAXN][2],ans_min[MAXN],ans_max[MAXN];
int main() { int m,n,h_max = 0,t_max = 0,h_min = 0,t_min = 0,t;
que_min[0][0] = -MAX_INT; que_max[0][0] = MAX_INT; scanf("%d %d",&n,&m); for(int i = 1;i <= n;i ++) { scanf("%d",&t); while(t <= que_min[t_min][0] && t_min >= h_min) { t_min --; } t_min ++; que_min[t_min][0] = t; que_min[t_min][1] = i; while(que_min[h_min][1] <= i - m) { h_min ++; } ans_min[i] = que_min[h_min][0]; while(t >= que_max[t_max][0] && t_max >= h_max) { t_max --; } t_max ++; que_max[t_max][0] = t; que_max[t_max][1] = i; while(que_max[h_max][1] <= i - m) { h_max ++; } ans_max[i] = que_max[h_max][0]; } for(int i = m;i <= n;i ++) printf("%d ",ans_min[i]); printf("\n"); for(int i = m;i <= n;i ++) printf("%d ",ans_max[i]); printf("\n"); return 0; }
|