模板 可並堆

2021-07-11 12:54:59 字數 1359 閱讀 7784

想學非旋轉的treap 然後看到裡面提到斜堆 順便學了學可並堆

可並堆

1.左偏樹

其實他介紹了4種可並堆= =

2.斜堆

好像說是類似平衡樹里的 splay

merge(a,b) >b.val 大根堆

merge(a.r,b)

swap(a.l,a.r)

細節什麼的還有一點= =

大體思想是合併a和b時 先合併a的右兒子和b 這個新堆是a的新右二子 然後交換a的左右兒子

就像splay一樣不明覺厲 均攤複雜度o(logn)

可並堆的操作 和基礎的堆的操作貌似一毛錢關係都沒有了呢= =

這是乙個斜堆

#include

#include

#include

using namespace std;

const int n=100005;

struct node

}h[n];

int fa[n];

int n,m;

int find(int

x)int merge(int

x,int

y)int main()

scanf("%d",&m);

for(int i=1;i<=m;i++)

scanf("%d

%d",&x,&y);

x=find(x);y=find(y);

//printf("%d

%d\n",x,y);

if(x==y)

h[x].val/=2;h[y].val/=2;

int rootx,rooty,root;

rootx=merge(h[x].ls,h[x].rs);fa[rootx]=rootx;

h[x].clear();fa[x]=x;

rootx=merge(rootx,x);fa[rootx]=rootx;

rooty=merge(h[y].ls,h[y].rs);fa[rooty]=rooty;

h[y].clear();fa[y]=y;

rooty=merge(rooty,y);fa[rooty]=rooty;

root=merge(rootx,rooty);fa[root]=root;

printf("%d\n",h[root].val);

//for(int j=1;j<=5;j++) printf("%d

%d%d\n",j,h[j].ls,h[j].rs);}}

左偏樹 可並堆 模板

我想您應該會二叉堆吧,它包含三個操作,這裡與小根堆為例 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 ...

模板 左偏樹(可並堆)

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