单调队列一般用于求区间内的最值问题
例题:
P1886 滑动窗口
P2032 扫描
算法核心
维护一个单调递增或递减的双端队列
队头即是区间的最值
用一个结点存下标和值
struct node
{
int index;
int value;
}no;
为了维护单调性需要进行删尾操作
while(!dq.empty()&&dq.back().value<=x)
dq.pop_back();
更新区间最值需要进行去头操作
if(!dq.empty()&&(i-dq.front().index)>=k)
dq.pop_front();
去头删尾后插入当前结点
no.index=i;
no.value=x
dq.push_back(no);
附P2032扫描完整代码
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
struct node
{
int index;
int value;
}no;
int main()
{
ios::sync_with_stdio(false);
deque<struct node>dq;
vector<int> ans;
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
if(!dq.empty()&&(i-dq.front().index)>=k)
dq.pop_front();
while(!dq.empty()&&dq.back().value<=x)
dq.pop_back();
no.index=i;
no.value=x;
dq.push_back(no);
if(i>=k) ans.push_back(dq.front().value);
}
for(int i=0;i<ans.size();i++)
{
cout<<ans[i]<<endl;
}
return 0;
}