P1886. 单调队列

考点

  • 单调队列
  • 滑动窗口

题解

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
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 50;
int n, k, a[maxn];
int head, tail, q[maxn];

int main() {
cin >> n >> k;
for (int i = 1; i <= n; ++i) cin >> a[i];
// 区间最小
for (int i = 1; i <= n; ++i) {
// 删除不在范围内的元素
while (head < tail && i >= q[head] + k) ++head;
// 维持单调性
while (head < tail && a[i] < a[q[tail - 1]]) --tail;
q[tail++] = i;
if (i >= k) cout << a[q[head]] << " ";
}
// 区间最大
cout << endl, head = tail = 0;
for (int i = 1; i <= n; ++i) {
while (head < tail && i >= q[head] + k) ++head;
while (head < tail && a[i] > a[q[tail - 1]]) --tail;
q[tail++] = i;
if (i >= k) cout << a[q[head]] << " ";
}
return 0;
}

思路

滑动窗口的模板题,直接看代码即可