1. 程式人生 > >單調隊列單調棧

單調隊列單調棧

ron div 信息 別人 禮物 uri span 題目 體驗

單調隊列單調棧

Tags:數據結構

更好閱讀體驗:https://www.zybuluo.com/xzyxzy/note/1041449


一、概述

單調隊列單調棧是很基礎的數據結構,常用來優化一些東西比如說優化DP
那麽大概意思就是在棧或隊列中按照某關鍵字單調維護信息,從而實現一些功能

其實很久之前接觸過單調隊列和單調棧,但一直沒有刷題,趁這兩天被LCT弄暈的時候復習下這些
先看題

二、題單

普及-

  • [x] P1886 滑動窗口 https://www.luogu.org/problemnew/show/P1886
  • [x] P3088 [USACO13NOV]擠奶牛 https://www.luogu.org/problemnew/show/P3088
  • [x] P1714 切蛋糕 https://www.luogu.org/problemnew/show/P1714
  • [x] P2216 [HAOI2007]理想的正方形 https://www.luogu.org/problemnew/show/P2216
  • [x] P2564 [SCOI2009]生日禮物 https://www.luogu.org/problemnew/show/P2564

普及

  • [x] P3512 [POI2010]PIL-Pilots https://www.luogu.org/problemnew/show/P3512
  • [x] P2698 [USACO12MAR]花盆Flowerpot https://www.luogu.org/problemnew/show/P2698
  • [x] P2422 良好的感覺 https://www.luogu.org/problemnew/show/P2422
  • [x] P2629 好消息,壞消息 https://www.luogu.org/problemnew/show/P2629
  • [ ] P2219 [HAOI2007]修築綠化帶
  • [ ] P2569 [SCOI2010]股票交易

三、做題經驗

用處

1、求滑動區間最大/最小值

例如:滑動窗口
比如求一個滑動區間的最小值,那麽維護一個從\(head\)\(tail\)單調遞增的隊列,那麽每次滑動從\(head\)刪數,在\(tail\)處加數的時候寫while(Q[tail]>=x&&head<=tail)tail++;

意思就是存在在一個數\(A\)後面還比\(A\)小的數\(B\),那麽這區間取\(B\)肯定會更優,\(A\)對答案產生不了貢獻於是在隊列中刪掉

2、求某數左邊第一個小於它的數

這個想了很久,最後別人告訴我用單調棧維護
維護一個自棧底至棧頂遞減的單調棧,每次加入一個數\(x\),判斷while(zhan[top]>=x&&top)top--;這麽做就可以保證zhan[top]<x找到第一個比\(x\)小的數了,而且還有利於下次尋找答案
例題:良好的感覺

套路

1、常與二分答案和前綴和連用

這類題目經常求最大或最小的什麽,就是二分答案的套路了
例如:花盆Flowerpot、好消息,壞消息

註意事項

1、使用單調隊列的時候千萬記得時刻head<=tail+1

通法

先想出線段樹的方法再用單調隊列優化掉一個\(log\)

單調隊列單調棧