单调队列
概念
单调队列,即单调递增或单调递减的队列,其中元素从队尾入队,从队首或队尾出队。
应用
单调队列一般用于求区间内的最值问题。
列题
先看代码
#include <bits/stdc++.h> using namespace std; int n, m; int q1[1000001], q2[1000001]; int a[1000001]; int min_deque() { int h = 1, t = 0; for (int i = 1; i <= n; i++) { while (h <= t && q1[h] + m <= i) h++; while (h <= t && a[i] < a[q1[t]]) t--; q1[++t] = i; if (i >= m) printf("%d ", a[q1[h]]); } cout << endl; } int max_deque() { int h = 1, t = 0; for (int i = 1; i <= n; i++) { while (h <= t && q2[h] + m <= i) h++; while (h <= t && a[i] > a[q2[t]]) t--; q2[++t] = i; if (i >= m) printf("%d ", a[q2[h]]); } } int main() { cin >> n >> m; for (int i = 1; i <= n; i++) scanf("%d", &a[i]); min_deque(); max_deque(); return 0; }
说明:这道题,求的是一个区间内的最大值和最小值。对于数组中的某一个元素,我们只要关心它自己和它前k-1个数即可。
那么如何用队列处理呢?先简单说一下解题思路,以求最小值为例:一开始数组下标i为0,我们向队列里不停的放元素,并且一直保持队首位元素为最小值,直到第k个数,此时队首元素即为前k个数的最小值。然后我们把队首输出。继续往下走,走的过程中把队列中下标超出(i-k+1)~i区间范围的数踢掉,继续保持队首元素为区间内最小值,然后输出队首元素。
简单归纳一下,对于每一次循环,我们要做的就是:先踢掉超出区间范围的元素,放入元素并保证队首为数组中当前区间的最小值,输出队首,往复。队列内储存的就是放入元素之前区间内单调递增的最小值序列。

浙公网安备 33010602011771号