單調棧 單調佇列

2022-05-19 03:05:06 字數 1932 閱讀 5638

感覺我有限的智力難以理解,因此寫下來研究一下(

顧名思義,單調佇列就是乙個佇列內容有單調性的佇列(

我們可以用單調佇列來維護一列資料中,某長度段連續的子區間中的最大/最小值

例如,給定一串數字,求其每個長度為m的連續子區間的最小值

相較於st表,線段樹等資料結構,單調佇列均攤複雜度o(n),會快很多

以下以乙個遞減的單調隊列為例,簡單描述一下如何構造單調佇列:

在區間往後移動了一位後,我們假定新出現的數字為a

單調佇列的隊首是以前加入的,那麼它可能不在新的區間中,進行判斷是否需要將其刪除

如果a比隊尾的數字小,沒有破壞單調性,我們可以直接把a加入隊尾

如果a比隊尾的數字大,因為a是新加入的數字,它可能在未來的某個區間中成為區間最大值,而在隊中,且比a小的數字一定存在於包含a的區間中,且沒有a大,所以沒用刪掉完事

這樣我們就構造出了乙個單調佇列

以下** 洛谷:p1886 滑動視窗 /【模板】單調佇列

#include #include #include #include #include #include #include#include#include#includeusing namespace std;

typedef long long ll;

typedef pairp;

int n, k;

struct node

;}que[1000000+5],que2[1000000+5];

int dataa[2000000];

int ans1[1000000+5],ans2[1000000+5];

int main()

for (int i = k - 1; i < n; i++)cout << ans2[i] << ' ';

cout << "\n";

for (int i = k - 1; i < n; i++)cout << ans1[i] << ' ';

}

單調棧就是棧內元素出棧序列單調有序的棧

沒了

要實現單調棧,我們只需要進行一下操作(以下操作是單調遞增棧,即出棧序列遞增)

我們要想令乙個值a入棧時,首先檢查棧頂元素是否大於a

棧頂元素大於等於a,a可以直接入棧

棧頂元素小於a,一直將棧頂元素出棧,直到棧頂元素大於a,隨後a入棧

ps.我們構造單調棧時,棧內儲存的是元素的下標,而不是元素的值

那麼這玩意有啥用呢(

使用單調棧,我們可以解決諸如尋找數列中某個數之前/後第乙個大於/小於它的數的問題

正確性:

我們以尋找某個數前,第乙個大於他的數為例

構造乙個單調遞增的棧,設當前數為a,此時

以下**:洛谷:p5788 【模板】單調棧

#include #include #include #include #include #include #include#include#include#include#include#define lc(i) (2*i+1)

using namespace std;

typedef long long ll;

typedef pairp;

int n, k;

stacksk;

ll dataa[3000000 + 5];

ll ans[3000000 + 5];

int main()

for (int i = 0; i < n; i++)cout << ans[i]+1 << ' ';

}

單調棧,單調佇列

大多數借鑑了 單調佇列是什麼呢?可以直接從問題開始來展開。poj 2823 給定乙個數列,從左至右輸出每個長度為m的數列段內的最小數和最大數。數列長度 n 106,m n 我們知道,解法 在暴力列舉的過程中,有乙個地方是重複比較了,就是在找當前的f i 的時候,i的前面其它m 1個數在算f i 1 ...

單調棧 單調佇列

單調棧 單調佇列是在棧和佇列的基礎上加上單調結構的資料結構。如果乙個元素入棧或入隊,他會檢查之前的元素,如果之前的元素不可能是答案的解,那麼就彈出元素,使得當前元素入棧或入隊。leetcode 239 滑動視窗最大值 此題是單調佇列,每次遇到乙個元素,一直從隊尾彈出,直到隊尾元素大於該元素為止。還需...

單調棧 單調佇列

啊學完了來寫個總結吧 顧名思義,單調,就是指色彩單一某乙個容器裡面的元素都是遞增或遞減的,而單調棧和單調佇列就是這個容器。單調棧 單調棧模板 其他的我就不說了,講下為什麼單調棧是從後往前掃瞄 當我們在判斷乙個數後面第乙個比它大的數時,前提是後面的數已經被處理了,所以我們要從後往前掃瞄。我做了兩種做法...