单调队列模板浅谈

什么是单调队列?

百度百科

单调队列,即单调递减或单调递增的队列。

单调队列能干什么?

实现快速寻找区间的最大值与最小值

如何实现单调队列?(这里使用了STL的deque)

①建立结构体

因为我们之后要判断队首的元素是不是已经超出了滚动窗口,所以得把每个值记录他原来的位置

struct node
{
    int num,id;
};

②判断原来的队首是不是还在滚动窗口内(并且输出当前的队首)

    if(q.front().id+m<i)
    q.pop_front();
    cout<<q.front().num<<"\n";

③对新进的数进行插入

(1)按照条件删除队尾的数,如果是单调增的单调序列那么删掉队尾大于等于当前值的值,这样求的就是滚动窗口内的最小值

(2)插入当前数据

    while(!q.empty()&&q.back().num>=a[i])
    q.pop_back();
    q.push_back((node){a[i],i});

完整代码(洛谷 P1440 求m区间内的最小值)

#include <bits/stdc++.h>
using namespace std;
struct node
{
    int num,id;
};
deque<node> q;
int a[2000005];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    cin>>a[i];
    for(int i=1;i<=n;i++)
    {
        if(q.empty())
        cout<<"0\n";
        else
        {
            if(q.front().id+m<i)
            q.pop_front();
            cout<<q.front().num<<"\n";
        }
        while(!q.empty()&&q.back().num>=a[i])
        q.pop_back();
        q.push_back((node){a[i],i});
    }
} 

猜你喜欢

转载自www.cnblogs.com/baccano-acmer/p/9997514.html