1. 程式人生 > >單調佇列模板淺談

單調佇列模板淺談

什麼是單調佇列?

百度百科

單調佇列,即單調遞減或單調遞增的佇列。

單調佇列能幹什麼?

實現快速尋找區間的最大值與最小值

如何實現單調佇列?(這裡使用了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});
    }
}