滑动窗口
求窗口内最大值
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
const int N=1e6+10;
const int INF=0x3f3f3f3f;
int read()
{
	int x=0,f=0,c=getchar();
	while(c<'0'||c>'9'){if(c=='-') f=1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return f?-x:x;
}
int n,k;
int a[N];
deque<int> q;
int main()
{
	n=read(); k=read();
	for(int i=1;i<=n;i++) a[i]=read();
	q.push_back(1); 
	for(int i=1;i<=n;i++)
	{
		while(q.size()&&i-q.front()+1>k) q.pop_front();
		while( q.size()&&a[i]<a[q.back()] ) q.pop_back();
		q.push_back(i);
		if(i>=k) printf("%d ",min(a[i],a[q.front()]));
	}
	puts("");
	while(q.size()) q.pop_front(); 
	q.push_back(1); 
	
	for(int i=1;i<=n;i++)
	{
		while(q.size()&&i-q.front()+1>k) q.pop_front();
		while( q.size()&&a[i]>a[q.back()] ) q.pop_back();
		q.push_back(i);
		if(i>=k) printf("%d ",max(a[i],a[q.front()]));
	}
	
}
注意:
我们先把当前决策入队 再出队 这样的话能够防止队列为空 并且会出现自己向自己转移这种情况
单调队列:求固定区间内的最大值 优于st表
q.size()要写到判断条件的前面 否则会RE
这里要注意和最大子序和的区分:
关于是先入队当前决策再更新答案 还是先更新答案在入队决策的问题:
如果可能从当前状态来转移的话  那么就应该先入队决策 用此来去除掉前面的内容
如果当前状态不能入队当前决策 则应该先更新答案
例如尝试如下反例:
4 3
3 3 3 5 8
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号