左偏樹 可並堆 模板

2021-08-10 20:25:03 字數 2661 閱讀 4582

我想您應該會二叉堆吧,它包含三個操作,這裡與小根堆為例: 1、

查詢最小值 2、

彈出最小值 3、

插入乙個值

可以使用st

l 的pr

iori

ty_que

ue實現,也可以用pb_ds中的庫實現,當然也可以手寫反正我不會,筆者是用的系統堆(包含在庫al

gori

thm

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define rg register

#define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);

using

namespace

std;

inline

int gi()

inline

bool cmp(const

int &a,const

int &b)//cmp存小根堆

struct heap

inline

void push(int x)

inline

int top()

inline

void pop()

inline

bool empty()

}q;int main()

return

0;}

但是我要講的並不是二叉堆,所以一筆帶過(不懂的可以去網上搜,一點也不難)。

什麼叫 可並

堆 呢?顧名思義,就是可以合併的堆,沒錯,可並堆就是可以合併的堆,它支援二叉堆的操作,而且還支援lo

g(n)

把兩個堆合併。

此時,stl

就不行了(pb

_ds 還是可以滴)。所以我們要手寫可並堆,而我們今天要講的左偏樹(li

ftis

ttre

e ),就是其中的一種。

什麼是左偏樹咧?首先,我們又顧名思義一下,它很明顯一棵樹。沒錯!其實它就是一棵樹,而且是顆二叉樹。

它的節點上存

4 個值:左、右子樹的位址,權值,距離。權值就是丟進去的數值。距離表示這個節點到它子樹裡面最近的葉子節點的距離。葉子節點距離為0。

而既然它是一種特殊的資料結構,那自然有它自己的性質。下面介紹左偏樹的

4 個性質,自己仔細想一想(還是以小根堆為例): 1、

節點的權值小於其左右兒子的權值 2、

節點左兒子的距離不小於右兒子的距離(注意只是距離,不代表節點數和深度也是如此) 3、

節點的距離等於右兒子的距離+1

4、乙個n

個節點的左偏樹距離最大為lo

g(n+

1)−1

性質講完了,所以——

下面是操作:1、

合併:

我們假設a的根節點小於等於b的根節點(否則交換a,b),把a的根節點作為新樹c的根節點,剩下的事就是合併a的右子樹和b了。合併了a的右子樹和b之後,a的右子樹的距離可能會變大,當a的右子樹 的距離大於a的左子樹的距離時,性質二會被破壞。在這種情況下,我們只須要交換a的右子樹和左子樹就能滿足條件。

而且因為a的右子樹的距離可能會變,所以要更新a的距離=右兒子距離+1。這樣就合併完了。

**:

int merge(int x,int y)
2、

刪除,取出最小值

為什麼放一起??

因為太容易了。。。

刪除:把兩顆子樹一合併,就完了。

取出:找根節點即可。

inline

void pop(int a)

inline

int top(int a)

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define rg register

#define file(x) freopen(x".in","r",stdin);

using

namespace

std;

inline

int gi()

#define n 100010

class liftist_tree

int merge(int x,int y)

inline

int top(int a)

inline

void pop(int a)

inline

int getf(int x)

}t;

int main()

if(opt==2)

}return

0;}

tips:評測位址

左偏樹(可並堆)模板

待 參考資料1 題意 有n個小根堆,一開始每個小根堆都只有乙個數,現在要進行m次操作,操作有兩種 1,x,y 將第x個數所在堆和第y個數所在堆合併 如果x或y已經被刪除則無視這次操作 2,x 查詢第x個數所在堆的最小數並刪除這個數 如果x或y已經被刪除則輸出 1 資料範圍 n,m 1e5 code ...

模板 左偏樹(可並堆)

如題,一開始有n個小根堆,每個堆包含且僅包含乙個數。接下來需要支援兩種操作 操作1 1 x y 將第x個數和第y個數所在的小根堆合併 若第x或第y個數已經被刪除或第x和第y個數在用乙個堆內,則無視此操作 操作2 2 x 輸出第x個數所在的堆最小數,並將其刪除 若第x個數已經被刪除,則輸出 1並無視刪...

模板 左偏樹(可並堆)

總的來說,可並堆仍然具有堆的性質,即 父節點和孩子節點之間的 key 值大小關係恆定。在此基礎上,可並堆增加了可以快速合併的操作。直觀上來講,因為乙個二叉堆是採用完全二叉樹的方式進行儲存的,這是乙個極其平衡的資料結構,但是也正是因為平衡,使得在合併的時候需要花很大力氣來再次調整成平衡的結構。而對於左...