模板单调队列

单调队列

有一个长为 nn的序列 a,以及一个大小为 k 的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。

例如:

The array is [1,3,-1,-3,5,3,6,7][1,3,1,3,5,3,6,7], and k = 3k=3。

输入格式

输入一共有两行,第一行有两个正整数 n,k。 第二行 nn个整数,表示序列 a

输出格式

输出共两行,第一行为每次窗口滑动的最小值
第二行为每次窗口滑动的最大值

 

#include<iostream>
using namespace std;
int n,k,i,head,tail;
const int Size=1000005;
long long a[Size];
long long sum[Size];
long long q[Size];
long long Fmax[Size];
long long Fmin[Size];
void get()
{
cin>>n>>k;
for(i=1;i<=n;i++)
{
cin>>a[i];
}
}
void MAX()
{
head=1;
tail=0;
for(i=1;i<=n;i++)
{
while((sum[head]<i-k+1)&&head<=tail)
head++;
while((q[tail]<=a[i])&&head<=tail)
tail--;
sum[++tail]=i;
q[tail]=a[i];
Fmax[i]=q[head];
}
}
void Min()
{
head=1;
tail=0;
for(i=1;i<=n;i++)
{
while((sum[head]<i-k+1)&&head<=tail)
head++;
while((q[tail]>=a[i])&&head<=tail)
tail--;
sum[++tail]=i;
q[tail]=a[i];
Fmin[i]=q[head];
}
}
int main()
{
get();
MAX();
Min();
for(i=k;i<=n;i++)
cout<<Fmin[i]<<" ";
cout<<endl;
for(i=k;i<=n;i++)
cout<<Fmax[i]<<" ";
}

 

 

posted @ 2020-08-23 06:37  weidan01  阅读(65)  评论(0)    收藏  举报