洛谷 3377 模板 左偏樹(可並堆)

2021-07-31 13:02:39 字數 1079 閱讀 6927

題目傳送門

作為乙個合格的蒟蒻,我們當然在學每一種演算法後都要去做一些和這種演算法有關的模板題。

毫無疑問,這是一道左偏樹的模板題。

伏地膜大佬,這位大佬對左偏樹的解釋十分到位。

左偏樹就是在堆的基礎上加上了距離的概念。

距離指的是每乙個節點到離他最近的不滿節點的距離。若乙個節點的左兒子或右兒子為空,則該節點是乙個不滿節點。

左偏樹有兩個特殊的性質:

1.乙個節點的左兒子的距離大於等於它的右兒子的距離

2.乙個節點的距離等於它的右兒子的距離加一

相對於堆,左偏樹的合併操作在時間複雜度上更優,就是有了上述的距離的概念。

合併的基本思想:

1.若乙個空左偏樹和乙個非空左偏樹合併,返回非空左偏樹。

2.若兩個左偏樹均不為空,則取根節點較小的點作為新左偏樹的根節點,然後合併根節點較小的左偏樹和另一左偏樹。

3.若新左偏樹的右兒子的距離大於左兒子的距離,交換左右兒子。

4.新左偏樹的距離等於它的右兒子的距離加一,返回新左偏樹。

就這樣吧。蒟蒻還是需要多刷題來熟練演算法。

附上ac**:

#include #include #include #define n 100010

using namespace std;

int n,m,x,y,o,dis[n],w[n],f[n],ls[n],rs[n];

inline void read(int& a)

while (isdigit(c)) a=a*10+c-'0',c=getchar();

a*=f;return;

}inline int gf(int x)

inline int hb(int x,int y){

if (!x) return y;

if (!y) return x;

if (w[x]>w[y]||(w[x]==w[y]&&x>y)) swap(x,y);

rs[x]=hb(rs[x],y);

f[rs[x]]=x;

if (dis[ls[x]]

洛谷P3377 模板 左偏樹(可並堆)

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

洛谷 P3377 模板 左偏樹(可並堆)

有 n nn 個小根堆,每個堆只有乙個數,進行兩種操作 1 x y將第 x,y x,yx,y 個數分別在的小根堆合併 2 x輸出第 x xx 個數所在的的堆的最小數,並將其刪除,有多個則刪除最先輸入的,若第 x xx 個數已刪除,則輸出 1 1 1思路 左偏樹 include include def...

洛谷 P3377 模板 左偏樹(可並堆)

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