---恢复内容开始---
一道经典的单调队列题目
单调指的是元素的规律呈现为一种单调性,递增,递减,或者自定义
队列指的是只能从队首和队尾进行操作(所以单调队列也可以用STL的deque实现),但单调队列只需要队首的弹出、队尾的插入和弹出
题目的要求是每连续k个数中的最大值和最小值,以维护最大值为例,对于任意在范围内,且在
---恢复内容结束---
### 一道经典的单调队列题目单调指的是元素的规律呈现为一种单调性,递增,递减,或者自定义1576249-20190816123042323-327652433.png
队列指的是只能从队首和队尾进行操作(所以单调队列也可以用STL的deque实现),但单调队列只需要队首的弹出、队尾的插入和弹出
题目的要求是每连续k个数中的最大值和最小值,以维护最大值为例,对于任意在范围内,且在队列中的数x,y,新进队一个数z,z > x && z > y,那么z从队尾进队,x,y出队
Code:
#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> using namespace std; const int maxn = 1000100; int n, k; int q[maxn], a[maxn]; void getmin() { int head = 0, tail = 0; for (int i = 1; i < k; i++) { while (head <= tail && a[q[tail]] >= a[i]) tail--; q[++tail] = i; } for (int i = k; i <= n; i++) { while (head <= tail && a[q[tail]] >= a[i]) tail--; q[++tail] = i; while (q[head] <= i - k) head++; printf("%d ", a[q[head]]); } } void getmax() { int head = 0, tail = 0; for (int i = 1; i < k; i++) { while (head <= tail && a[q[tail]] <= a[i]) tail--; q[++tail] = i; } for (int i = k; i <= n; i++) { while (head <= tail && a[q[tail]] <= a[i]) tail--; q[++tail] = i; while (q[head] <= i - k) head++; printf("%d ", a[q[head]]); } } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); scanf("%d%d", &n, &k); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); getmin(); printf("\n"); getmax(); return 0; }