題面戳我
題目描述
如題,一開始有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 5
1 5 4 2 3
1 1 5
1 2 5
2 21 4 2
2 2
輸出樣例#1:
1
2
說明
當堆裡有多個最小值時,優先刪除原序列的靠前的,否則會影響後續操作1導致wa。
時空限制:1000ms,128m
資料規模:
對於30%的資料:n<=10,m<=10
對於70%的資料:n<=1000,m<=1000
對於100%的資料:n<=100000,m<=100000
左偏樹模板題,考慮到要講所以就把陳年**翻出來寫一寫題解。
我們考慮到左偏樹的乙個非常優秀的性質:樹高的期望是\(logn\)
所以判斷是否在同乙個堆中,只要暴力跳堆頂即可。
(其實也是可以寫個並查集的啦)
其他就好說了。
#include#include#includeusing namespace std;
const int max=100005;
int key[max],ls[max],rs[max],fa[max],dis[max],del[max],n,m;
int gi()
return x*w;
}int merge(int a,int b)
void delete(int a)
int find(int x)
int main()
else}}
return 0;
}
luogu3377 左偏樹 可並堆
題目鏈結 左偏樹的模板題,參考左偏樹學習筆記 對於這道題我是用乙個並查集維護出了哪些點是在同一棵樹上,也可以直接log的往上跳尋找根節點 include include include include include includeusing namespace std typedef long l...
洛谷 3377 模板 左偏樹(可並堆)
題目傳送門 作為乙個合格的蒟蒻,我們當然在學每一種演算法後都要去做一些和這種演算法有關的模板題。毫無疑問,這是一道左偏樹的模板題。伏地膜大佬,這位大佬對左偏樹的解釋十分到位。左偏樹就是在堆的基礎上加上了距離的概念。距離指的是每乙個節點到離他最近的不滿節點的距離。若乙個節點的左兒子或右兒子為空,則該節...
luoguP3377 模板 左偏樹(可並堆)
題目描述 如題,一開始有n個小根堆,每個堆包含且僅包含乙個數。接下來需要支援兩種操作 操作1 1 x y 將第x個數和第y個數所在的小根堆合併 若第x或第y個數已經被刪除或第x和第y個數在用乙個堆內,則無視此操作 操作2 2 x 輸出第x個數所在的堆最小數,並將其刪除 若第x個數已經被刪除,則輸出 ...