1. 程式人生 > >蒟蒻的單調佇列orz,真的蒻

蒟蒻的單調佇列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

好啦!完結撒花✿✿ヽ(°▽°)ノ✿

【總有一天我會把我學過的所有演算法和所有寫過的模板題都寫成部落格的!!!這是一個 真flag】