题意:给你n个数,问你从1到n-k+1的连续k个数的最小值和最大值分别是多少
题解:单调队列,维护k个中的从小到大或从大到小,如果到我这一个比这里面所有的数都要大或小,就放到第一个,不燃放到我该放的位置,然后保证a[q]数组里单调上升或下降,q数组存这一位是第几个数,所以如果head位(最值)是不在这k个里的就往后找
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 10;
int q[maxn], a[maxn], n, k;
void Max() {
memset(q, 0, sizeof(q));
int tail = 0, head = 1;
for (int i = 1; i < k; i++) {
while (head <= tail && a[i] >= a[q[tail]]) tail--;
tail++;
q[tail] = i;
}
for (int i = k; i <= n; i++) {
while (head <= tail && a[i] >= a[q[tail]]) tail--;
tail++;
q[tail] = i;
while (q[head] < i - k + 1) head++;
printf("%d%c", a[q[head]], i == n ? '\n' : ' ');
}
}
void Min() {
memset(q, 0, sizeof(q));
int tail = 0, head = 1;
for (int i = 1; i < k; i++) {
while (head <= tail && a[i] <= a[q[tail]]) tail--;
tail++;
q[tail] = i;
}
for (int i = k; i <= n; i++) {
while (head <= tail && a[i] <= a[q[tail]]) tail--;
tail++;
q[tail] = i;
while (q[head] < i - k + 1) head++;
printf("%d%c", a[q[head]], i == n ? '\n' : ' ');
}
}
int main() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
Min();
Max();
return 0;
}