一道经典的单调队列题目
原题传送门
单调指的是元素的规律呈现为一种单调性,递增,递减,或者自定义1576249-20190816123042323-327652433.png
队列指的是只能从队首和队尾进行操作(所以单调队列也可以用STL的deque实现),但单调队列只需要队首的弹出、队尾的插入和弹出
题目的要求是每连续k个数中的最大值和最小值,以维护最大值为例,对于任意在范围内,且在队列中的数x,y,新进队一个数z,z > x && z > y,那么z从队尾进队,x,y出队
Code:
#include <bits/stdc++.h>
const int N = 1000010;
int n, k;
int q[N], a[N];
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
f = (ch == '-') ? -1 : 1, ch = getchar();
while (isdigit(ch))
x = x * 10 + (ch - '0'), ch = getchar();
return x * f;
}
void GetM(int d)
{
std::memset(q, 0, sizeof(q));
int head = 0, tail = 0;
for (int i = 1; i <= n; i++)
{
if (d ^ 1)
while (head <= tail && a[q[tail]] >= a[i])
tail--;
else
while (head <= tail && a[q[tail]] <= a[i])
tail--;
q[++tail] = i;
if (i >= k)
{
while (q[head] <= i - k)
head++;
std::cout << a[q[head]] << ' ';
}
}
}
int main()
{
n = read(), k = read();
for (int i = 1; i <= n; i++)
a[i] = read();
GetM(0);
std::cout << '\n';
GetM(1);
return 0;
}