题目描述
给定一个数列,从左至右输出每个长度为m的数列段内的最小数和最大数
题目解析
用单调队列来完成
维护好一个正确的单调队列后,队头就是当前区间的最大值或最小值
代码
#include<cstdio>
#define N 10000005
using namespace std;
int n,m,h=1,t=1;
int a[N],list[N];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
list[1]=1;
for(int i=1;i<=n;i++)
{
while(h<=t&&a[list[t]]>=a[i]) t--;//删尾
list[++t]=i;//进队
while(i-list[h]>=m) h++;//去头
if(i>=m) printf("%d ",a[list[h]]);//最小值在队头
}//单调递增
printf("\n");
h=1;t=1;
list[1]=1;//初始化
for(int i=1;i<=n;i++)
{
while(h<=t&&a[list[t]]<=a[i]) t--;//删尾
list[++t]=i;//进队
while(i-list[h]>=m) h++;//去头
if(i>=m) printf("%d ",a[list[h]]);//最大值在队头
}//单调递减
}