题目描述
现在有一堆数字共$N$个数字($N<=10^6$),以及一个大小为$k$的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。
例如:
The array is [1 3 -1 -3 5 3 6 7], and $k = 3$.

输入输出格式
输入格式:
输入一共有两行,第一行为$n,k$。
第二行为$n$个数(<INT_MAX).
输出格式:
输出共两行,第一行为每次窗口滑动的最小值
第二行为每次窗口滑动的最大值
输入输出样例
输入样例#1:
8 3 1 3 -1 -3 5 3 6 7
输出样例#1:
-1 -3 -3 -3 3 3 3 3 5 5 6 7
说明
50%的数据,$n<=10^5$
100%的数据,$n<=10^6$
题解
单调队列の模板题
然后。。。。就这样辣?
注意维护队首和插入队尾就可以了
#include <map>
#include <list>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
//#pragma GCC optimize(2)
#define endl '
'
#define fast ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
int n,m;
int q1[1000005],q2[1000005];
int a[1000005];
inline int read() //快读
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x*=10;x+=(ch-'0');ch=getchar();}
return x*f;
}
int min_deque()
{
int L=1,r=0;
for (register int i=1;i<=n;i++)
{
while (L<=r && q1[L]+m<=i)
L++;
while(L<=r && a[i]<a[q1[r]])
r--;
q1[++r]=i;
if (i>=m)
cout<<a[q1[L]]<<" ";
}
cout<<endl;
}
int max_deque()
{
int L=1,r=0;
for (register int i=1;i<=n;i++)
{
while (L<=r && q2[L]+m<=i)
L++;
while (L<=r && a[i]>a[q2[r]])
r--;
q2[++r]=i;
if (i>=m)
cout<<a[q2[L]]<<" ";
}
}
int main()
{
fast;
cin>>n>>m;
for (register int i=1;i<=n;i++)
a[i]=read();
min_deque();
max_deque();
return 0;
}