如題,一開始有n個小根堆,每個堆包含且僅包含乙個數。接下來需要支援兩種操作:
操作1: 1 x y 將第x個數和第y個數所在的小根堆合併(若第x或第y個數已經被刪除或第x和第y個數在用乙個堆內,則無視此操作)
操作2: 2 x 輸出第x個數所在的堆最小數,並將其刪除(若第x個數已經被刪除,則輸出-1並無視刪除操作)
輸入格式:
第一行包含兩個正整數n、m,分別表示一開始小根堆的個數和接下來操作的個數。
第二行包含n個正整數,其中第i個正整數表示第i個小根堆初始時包含且僅包含的數。
接下來m行每行2個或3個正整數,表示一條操作,格式如下:
操作1 : 1 x y
操作2 : 2 x
輸出格式:
輸出包含若干行整數,分別依次對應每乙個操作2所得的結果。
輸入樣例#1:
5 51 5 4 2 3
1 1 5
1 2 5
2 21 4 2
2 2
輸出樣例#1:
12
當堆裡有多個最小值時,優先刪除原序列的靠前的,否則會影響後續操作1導致wa。
時空限制:1000ms,128m
資料規模:
對於30%的資料:n<=10,m<=10
對於70%的資料:n<=1000,m<=1000
對於100%的資料:n<=100000,m<=100000
樣例說明:
初始狀態下,五個小根堆分別為:、、、、。
第一次操作,將第1個數所在的小根堆與第5個數所在的小根堆合併,故變為四個小根堆:、、、。
第二次操作,將第2個數所在的小根堆與第5個數所在的小根堆合併,故變為三個小根堆:、、。
第三次操作,將第2個數所在的小根堆的最小值輸出並刪除,故輸出1,第乙個數被刪除,三個小根堆為:、、。
第四次操作,將第4個數所在的小根堆與第2個數所在的小根堆合併,故變為兩個小根堆:、。
第五次操作,將第2個數所在的小根堆的最小值輸出並刪除,故輸出2,第四個數被刪除,兩個小根堆為:、。
故輸出依次為1、2。
左偏樹板子題;
1 #include2const
int maxn=1e6+10;3
intn,m;
4int f[maxn],s[maxn]=,d[maxn],l[maxn],r[maxn];
5 inline void swap_(int&x,int&y)
6int ff(int x)
7int merger(int a,int
b)16
inta,b,c;
17int
main()
29if(c==2)37
else puts("-1"
);38}39
}40return0;
41 }
左偏樹 可並堆 模板
我想您應該會二叉堆吧,它包含三個操作,這裡與小根堆為例 1 查詢最小值 2 彈出最小值 3 插入乙個值 可以使用st l 的pr iori ty que ue實現,也可以用pb ds中的庫實現,當然也可以手寫反正我不會,筆者是用的系統堆 包含在庫al gori thm include include...
左偏樹(可並堆)模板
待 參考資料1 題意 有n個小根堆,一開始每個小根堆都只有乙個數,現在要進行m次操作,操作有兩種 1,x,y 將第x個數所在堆和第y個數所在堆合併 如果x或y已經被刪除則無視這次操作 2,x 查詢第x個數所在堆的最小數並刪除這個數 如果x或y已經被刪除則輸出 1 資料範圍 n,m 1e5 code ...
模板 左偏樹(可並堆)
總的來說,可並堆仍然具有堆的性質,即 父節點和孩子節點之間的 key 值大小關係恆定。在此基礎上,可並堆增加了可以快速合併的操作。直觀上來講,因為乙個二叉堆是採用完全二叉樹的方式進行儲存的,這是乙個極其平衡的資料結構,但是也正是因為平衡,使得在合併的時候需要花很大力氣來再次調整成平衡的結構。而對於左...