左偏樹

最爱丁珰發表於2024-08-18

具體見OI-wiki,但是OI-wiki對左偏樹的“外節點”的定義好像錯了,其實應該就是指空節點;刪除任意一個數的那個部分就不用看了,沒啥用

\(f(k)\)表示\(\text{dist}\)\(k\)的左偏樹最少包含的點,則有\(f(k)≥2^k-1\)

證明:\(f(k)\)單調遞增,這是因為此時右子樹的\(\text{dist}\)肯定為\(k-1\),也就包含\(f(k-1)\)個點,算上根節點和左子樹,於是有\(f(k)\)單增

顯然\(f(1)≥2^1-1=1\)

假設當\(n=k-1\)時,\(f(n)≥2^n-1\);當\(n=k\)時,\(f(n)≥2^{k-1}-1+2^{k-1}-1+1=2^k-1\)(右子樹為\(f(k-1)\)個節點,左子樹至少為\(f(k-1)\)個節點,算上根節點),證畢

也就是說至少有\(\text{dist-1}\)層是滿二叉樹,於是時間複雜度得以保證

那麼對於這道題目,我們還需要用並查集去維護左偏樹。具體來說,每個左偏樹都對應一個並查集,而且左偏樹的根節點就是並查集的代表元素。於是前面三個操作都很容易解決了,但是第四個操作看起來要對並查集進行分離。實際上不用,這裡解鎖一個新操作,即並查集的換根操作。刪除左偏樹的根節點後,我們在並查集中不刪除代表元素;合併左兒子和右兒子之後,新的左偏樹的根作為並查集的代表元素,此時只需要將原來的根節點的父親指向新的根節點,新的根節點的父親指向自己就好了。易知這樣做不會影響答案

具體見打卡程式碼

相關文章