P1886 滑動窗口
GET 單調隊列
題目描述
現在有一堆數字共N個數字(N<=10^6),以及一個大小為k的窗口。現在這個從左邊開始向右滑動,每次滑動一個單位,求出每次滑動後窗口中的最大值和最小值。
例如:
The array is [1 3 -1 -3 5 3 6 7], and k = 3.
輸入輸出格式
輸入格式:
輸入一共有兩行,第一行為n,k。
第二行為n個數(<INT_MAX).
輸出格式:
輸出共兩行,第一行為每次窗口滑動的最小值
第二行為每次窗口滑動的最大值
看完我第一感覺是用一種能夠刪除任意元素的堆,但是這樣還要用hash維護每個元素在線性表中的位置。所以——
第一次做時候去學了一個multiset,但是大概因為常數太大,T了三個點(multiset挺好用的,特別是有重復元素的時候。據資料 是用二叉平衡樹寫的,我覺得它挺像能刪除任意元素的堆)
第二次看了看題解,看到了單調隊列。花了一些時間仔細看懂,然後覺得單調隊列原來也不是很難嘛
單調隊列:
這個東西元素值(元素也有可能是一個標號,那麽元素值就是標號為下標的值)是單調的。最初我看的時候覺得很奇怪,因為我覺得單調隊列裏面的元素值應該是完全合法的(即都是符合題意的)。不過這裏很巧妙。
比如說我們要維護一個單調遞增的單調隊列,那麽隊頭應該是最小值、隊尾是最大值。我們現在插入一個元素,它只有兩種情況:1.小於隊尾元素 2.大於等於隊尾元素。對於每一個新的元素,由於它的時間戳最新,它們是都要被加進單調隊列中的。情況1時,顯然隊尾元素和新元素相比,既大又老,是肯定不優的(大:和新元素比不能作為最小值;老:比新元素先被排除,無效於之後操作);情況2時,因為新元素最新,即使它暫時沒有成為最小的,它也有可能在隊尾元素 老掉
由此看來,隊首與隊尾之間的元素暫時沒有操作:它們肯定比隊首大比隊尾小,但是有可能時間戳更老,即無效。所以當它們成為隊首元素時,需要對它們進行時間戳 / 有效性的判斷。這樣在需要用時才進行去除操作,比每次更新時間便更新元素的效率更高。
那麽這題只需要維護兩個單調隊列即可。
P1886 滑動窗口