/*****************************************************************
题目: Sliding Window(poj 2823)
链接: http://poj.org/problem?id=2823
题意: 给一个数列,找所有连续k个数的最小值和最大值。
算法: 单调队列(入门)
*******************************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mx=;
struct Q
{
int x;
int id;
};
Q q[mx];
int a[mx];
int main()
{
int n,k;
while (~scanf("%d%d",&n,&k))
{
for (int i=;i<=n;i++) scanf("%d",&a[i]);
int h=,r=,i;
///初始化队列,这步一定要加
for (int i=;i<;i++) q[i].id=;
///先把前k个元素放入队列
for (i=;i<=k;i++)
{
while (r>=h&&q[r].x>a[i]) r--; ///保证队列中元素递增,虽然有些元素会覆盖,但覆盖的元素
///是不会输出的元素。
q[++r].x=a[i];
q[r].id=i;
}
for (;i<=n;i++)
{
printf("%d ",q[h].x); ///由于队列只有k个元素,所以第一一定是最小的
while (q[h].id<=i-k) h++; ///删除一些元素,保证下标在i-k+1到i的元素在队列中
while (r>=h&&q[r].x>a[i]) r--;
q[++r].x=a[i];
q[r].id=i;
}
printf("%d\n",q[h].x);
///最大值求法和最小值一样
for (int i=;i<;i++) q[i].id=;
h=,r=;
for (i=;i<=k;i++)
{
while (r>=h&&q[r].x<a[i]) r--;
q[++r].x=a[i];
q[r].id=i;
}
for (;i<=n;i++)
{
printf("%d ",q[h].x);
while (q[h].id<=i-k) h++;
while (r>=h&&q[r].x<a[i]) r--;
q[++r].x=a[i];
q[r].id=i;
}
printf("%d\n",q[h].x);
}
}