蒟蒻的單調佇列orz,真的蒻
(……打了這麼久orz我今天才知道這玩意是啥意思……)
沒有老師就是飄啊……我居然學完樹狀陣列和線段樹連個佇列都不會……orz orz orz
這篇是單調佇列哦,不是優先佇列(優先佇列那種東西queue不就好了嘛)
咳咳咳廢話說的真多,回到正題
什麼是單調佇列
咳咳咳反正是給自己看的,直接舉個例子吧,比如一個從小到大的單調佇列,那麼這個佇列中的每個元素的下標應符合遞增,每個元素也應該符合遞增
跟優先佇列的區別應該是能看出來的吧……優先佇列基本上就是排序好的陣列了……(其實這麼說,只是因為我不知道該怎麼解釋)
單調佇列的演算法思想
原始陣列
下標 | 1 | 2 | 3 | 4 | 5 |
值 | 4 | 2 | 5 | 6 | 3 |
假如我們現在要將這整個陣列加入從小到大的單調佇列q
首先佇列必備的兩個指標:head tail
佇列本來為空,所以第一個元素直接入隊,tail++
下標 | 1 |
值 | 4 |
第二個元素2要入隊了,但這時候我們發現2<4,那麼如果將2直接加入佇列,顯然不符合其遞增的單調性,所以我們幹掉它的前一個元素(嚶嚶嚶就是這麼暴力),tail--,再把2入隊,tail++
下標 | 1 |
值 | 2 |
第三個元素是5,5>2,符合其單調性,所以5直接入隊tail++
下標 | 1 | 2 |
值 | 2 | 5 |
第四個元素是6,同上一步
下標 | 1 | 2 | 3 |
值 | 2 | 5 | 6 |
最後一個元素是3,同第二步,若要將3加入佇列,不僅要幹掉前面的6,tail--,前面的5也不能留!tail--(嗯就是這麼凶)
這時候的佇列就變成了這個樣子
下標 | 1 | 2 |
值 | 2 | 3 |
ok,操作完成啦✿✿ヽ(°▽°)ノ✿
程式碼實現
結合我們剛剛的演算法思想,我們就可以來搞一搞程式碼了QwQ
(s陣列儲存的是下標)
#include<bits/stdc++.h> using namespace std; int a[1000100],q[1000100],s[1000100]; int main() { int n,k,tail,head; scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) scanf("%d",&a[i]); head=1; tail=0; for (int i=1;i<=n;i++) { // cout<<"現在出場的是:"<<i<<endl; while (tail>=head&&a[i]<=q[tail]) { // cout<<"出隊(tail):"<<s[tail]<<' '<<q[tail]<<endl; tail--; } tail++; q[tail]=a[i]; s[tail]=i; while (s[head]<i-k+1) { // cout<<"出隊(head):"<<s[head]<<' '<<q[head]<<endl; head++; } // cout<<"現在的隊首是"<<s[head]<<" "<<q[head]<<endl; if (i>=k) printf("%d ",q[head]); } printf("\n"); head=1; tail=0; for (int i=1;i<=n;i++) { q[i]=0; s[i]=0; } for (int i=1;i<=n;i++) { // cout<<"現在出場的是:"<<i<<endl; while (tail>=head&&a[i]>=q[tail]) { // cout<<"出隊(tail):"<<s[tail]<<' '<<q[tail]<<endl; tail--; } tail++; q[tail]=a[i]; s[tail]=i; while (s[head]<i-k+1) { // cout<<"出隊(head):"<<s[head]<<' '<<q[head]<<endl; head++; } // cout<<"現在的隊首是"<<s[head]<<" "<<q[head]<<endl; if (i>=k) printf("%d ",q[head]); } printf("\n"); return 0; }
我手頭上沒有純裸題QwQ(其實就是懶QwQ)(咳咳主要是快下課了我想趕緊把這篇寫完)
其實就是兩個裸單調佇列加上隊首出隊操作而已,挺裸的一道題
(PS:調程式的時候我才知道!原來scanf不加&會.exe停止執行!printf加了&會輸出奇奇怪怪的東西!!!(好吧其實還是我蒻))
但我在這裡強烈安利一位大佬的題解QwQ!我就是看著他的題解學的單調佇列!這裡貼一下地址以便自己以後膜或者大家參觀QwQ(我這慘淡的訪問量到底是哪來的信心……)https://www.luogu.org/blog/hankeke/solution-p1886
好啦!完結撒花✿✿ヽ(°▽°)ノ✿