题解:滑动窗口 【单调队列】

  • N 2 N^2 N2 暴力应该都会
  • N l o g N NlogN NlogN 线段树,树状数组ST表随便搞
  • N N N单调队列
#include 
#include 
using namespace std;

#define ll long long
#define re register
#define gc getchar()
inline int read()
{
	re int x(0),f(1);re char ch(gc);
	while(ch<'0'||ch>'9') {if(ch=='-')f=-1; ch=gc;}
	while(ch>='0'&&ch<='9') x=(x*10)+(ch^48),ch=gc;
	return x*f;
}

const int N=1e6+5;
int n,k,a[N],q[N],num[N],f1[N],f2[N],head,tail;

void get_max()
{
	head=1,tail=0;
	for(int i=1;i<=n;++i)
	{
		while(num[head]<i-k+1&&head<=tail) ++head;
		while(a[i]<=q[tail]&&head<=tail) --tail;
		num[++tail]=i,q[tail]=a[i];
		f1[i]=q[head];
	}
	for(int i=k;i<=n;++i)
		cout<<f1[i]<<" ";
	cout<<endl;
}
void get_min()
{
	head=0,tail=1;
	for(int i=1;i<=n;++i)
	{
		while(num[head]<i-k+1&&head<=tail) ++head;
		while(a[i]>=q[tail]&&head<=tail) --tail;
		num[++tail]=i;q[tail]=a[i];
		f2[i]=q[head];
	}
	for(int i=k;i<=n;++i)
		cout<<f2[i]<<" ";
}

int main()
{
	n=read(),k=read();
	for(int i=1;i<=n;++i)
		a[i]=read();
	get_max();
	get_min();
	return 0;
}

你可能感兴趣的:(题解,DP)