经典的单调队列模板题
这是一个经典的模板题,大概意思代码注释里有
#include <bits/stdc++.h> using namespace std; const int maxn = 1e6 + 10; int a[maxn], du[maxn]; int n, m; int main() { while (~scanf("%d%d", &n, &m)) { for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); int head = 0, tail = 1; //定义头指针和尾指针 du[0] = 1; if (m == 1) printf("%d ", a[1]); for (int i = 2; i <= n; ++i) { if (i - du[head] >= m && (head < tail)) head++; //如果区间长度大于m则把最前面的删除,也就是head++操作 while (tail > head && a[du[tail - 1]] >= a[i]) //判断队尾元素是否大于刚刚进来的元素 tail--; // 如果是就把队尾删除,一直到前面一个元素小于等于它为止 du[tail++] = i; //记录最小值位置 if (i >= m) //窗口移动的过程输出最小值 printf("%d ", a[du[head]]); } printf("\n"); head = 0, tail = 1; du[0] = 1; if (m == 1) printf("%d ", a[1]); for (int i = 2; i <= n; ++i) //最大值同理 { if (i - du[head] >= m && (head < tail)) head++; while (tail > head && a[du[tail - 1]] <= a[i]) tail--; du[tail++] = i; if (i >= m) printf("%d ", a[du[head]]); } printf("\n"); } return 0; }