洛谷 P1886 滑動視窗 單調佇列

2022-02-13 14:25:08 字數 2101 閱讀 7895

現在有一堆數字共n個數字(n<=10^6),以及乙個大小為k的視窗。現在這個從左邊開始向右滑動,每次滑動乙個單位,求出每次滑動後視窗中的最大值和最小值。

例如:the array is [1 3 -1 -3 5 3 6 7], and k = 3.

輸入格式:

輸入一共有兩行,第一行為n,k。

第二行為n個數(輸出格式:

輸出共兩行,第一行為每次視窗滑動的最小值

第二行為每次視窗滑動的最大值

輸入樣例#1:

8 3

1 3 -1 -3 5 3 6 7

輸出樣例#1:

-1 -3 -3 -3 3 3

3 3 5 5 6 7

50%的資料,n<=10^5

100%的資料,n<=10^6

先理解文意:對於給定乙個長度為n的序列,找出所有長為k的區間的最大值(最小值)。

首先很多人會想到,列舉每乙個長為k的區間,然後遍歷一遍,找到最大值(最小值),這樣的時間複雜度是o(nk)的,顯然超時。

所以我們需要換一種思路。

單調佇列:單調佇列就是乙個一直保持單調性(遞增或遞減)的長度最大為k的雙端佇列。

我們維護這樣乙個單調佇列,使它隊首元素即為要求的最大值(最小值)。

所以本題的核心是:怎樣維護乙個單調佇列。

在此舉例求最大值:對於任意讀入的元素,我們不放設為in,首先判斷佇列是否為空,如果隊列為空,就一定要加入佇列。若不為空,就一直比較佇列末尾的元素,不放設為f,如果ff,所以在一定範圍內,答案有可能是in,但永遠不可能是f。(這裡有乙個有趣的模擬,如果一位oier比你年輕還比你強,那你就沒法超越他了。——kevin大佬)。還有乙個問題,就是滑動視窗長度最大是k,所以我們需要用結構體儲存每乙個數的編號和數值,如果in的編號和隊首的編號的差》=k,就把隊首砍掉,這是顯然的。

這樣,由於每乙個元素只進入佇列一次,所以時間複雜度就變成o(n)了。

話不多說,看**。

1 #include2 #include3 #include4 #include5 #include

6 #include7 #include8 #include

9 #include10 #include11 #include12 #include13 #include//

還是寫了一大堆沒用的標頭檔案

14using

namespace

std;

15int

n,k;

16int maxx[1000005],minn[1000005]; //

由於輸出要求,需要先用陣列存好答案

17struct num //

結構體建構函式,作用是在定義結構體的時候,就會給cnt和value賦值。用法具體看29行或者39行**

20};

21 dequeq1,q2; //

定義兩個雙端佇列,q1儲存最大值,q2儲存最小值

22void makeq1(int i,int

in)34

}35 q1.push_back(num(i, in

));36}37

}38void makeq2(int i,int

in)50

}51 q2.push_back(num(i, in

));52}53

}54intmain()

5566}67

for(int i=k;i<=n;i++) cout

"; //

注意輸出格式

68 cout<

69for(int i=k;i<=n;i++) cout

70return0;

71 }

ac**

單調佇列 洛谷P1886 滑動視窗

題目鏈結 dalao題解 題目給乙個長度為n的序列,然後給乙個值k,要求出長度為k的視窗在數列滑動過程中的最大值和最小值 圖示如下 比如給乙個長度為n 8的序列為 1 3 1 3 5 3 6 7 視窗長度是k 3 那麼視窗滑動中的 最小值就是 1 3 3 3 3 3 最大值就是 3 3 5 5 6 ...

洛谷P1886 滑動視窗 單調佇列

沒想到啊沒想到,時隔兩個月,我單調佇列又懵了 調了乙個小時,最後錯在快讀,啊!不過洛谷討論真好啊,感謝大佬!考前就不推新東西了,好好寫寫那些學過的東西 題目點這裡 我就不粘了自己點一下看吧 這題還有其他奇奇怪怪的做法,比如你可以當做rmq,用線段樹啊st表啊隨便你,不過單調佇列就可以了 單調佇列說到...

洛谷P1886 滑動視窗 單調佇列

給出n m role presentation n,m n,m和乙個含有 n role presentation n n個元素的數列,求每個連續的長度為 m role presentation m m的子串的最小值和最大值。暴力o n2 role presentation o n 2 o n2 可以...