概要:左偏樹是具有左偏性質的堆有序二叉樹,它相比於優先佇列,能夠實現合併堆的功能。
先orz國家集訓隊**
左偏樹的幾個基本性質如下:
節點的鍵值小於等於它的左右子節點的鍵值
節點的左子節點的距離不小於右子節點的距離
節點的距離等於右子節點的距離加一,由此可推出乙個引理和乙個定理:若左子樹的距離為一定值,則節點數最少的左偏樹是完全二叉樹
若一棵左偏樹的距離為k,則這顆左偏樹至少有2k+1-1個節點
4.一棵n個節點的左偏樹的距離最多為[log(n+1)]-1
左偏樹的節點定義:
structview codenode t[maxn];
初始化操作:
1view codevoid init(int
x) 6 }
基本的查詢雙親,是否屬於同個集合:
1view codeint find(int
x) 5
6bool same(int x, int
y)
左偏樹的基本操作
合併操作(事實上操作時始終把b插入a中)
函式返回的是合併後的樹的根節點
首先特判是否存在空樹
然後注意到左偏樹我們需要保證根節點鍵值不大於兩個子節點的鍵值,此處我們需要特判a、b的鍵值,決定swap函式的呼叫與否(維護性質1)
接著判斷a的左右子樹的距離,決定是否呼叫swap(維護性質2)
最後根據a右子樹的距離生成a的距離(維護性質3)
1view codeint unite(int x, int
y)
2.插入節點
將b節點視為一棵左偏樹,合併a、b即可
3.刪除最小(大)節點
等同於合併根節點的左右子樹(可能會涉及修改左右子樹的父親為自身)
1view codeint pop(int
x)
hdu-1512
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7view code#define inf 0x3f3f3f3f
8#define mod 1000000007
9 typedef long
long
ll;10
using
namespace
std;
11const
int maxn = 1e5 + 10;12
13int
n, m;
1415
struct
node t[maxn];
1819
void init(int
x) 24}25
26int find(int
x) 30
31bool same(int x, int
y) 34
35int unite(int x, int
y) 52
//53
int pop(int
x) 59
60void solve(int x, int
y) 68
69int main(int argc, const
char *ar**)
75 scanf("
%d", &m);
76while (m--) else84}
85}86return0;
87 }
左偏樹 模板
神經病也可以寫成右偏樹 具體左偏指左節點的距離 geq 右節點的距離 距離指離最近擁有空節點的節點的距離 乙個節點的值一定 或 leq 或 geq 或 其子節點的值 由於左偏性質,每次可以合併至右邊,維護左偏性質後就可以保證複雜度 被踩爆的板子 或者是我?include define ls lson...
模板 左偏樹
洛谷模板題 一聽左偏樹這個名字就感覺左偏。左偏樹是什麼,好像就是個堆,大根堆或小根堆,可以支援合併,取堆頂元素,刪除堆頂元素,插入元素的操作。一些說明 左偏樹節點除了應有的東西,還有鍵值和距離,鍵值用於比較大小,距離是什麼?距離是這樣定義的 節點i稱為外節點 external node 當且僅當節點...
模板 左偏樹
可在log複雜度合併的堆 每個節點有乙個距離,具體定義我不知道 1.滿足堆的性質 2.左子節點距離 右子節點 3.節點距離 右子節點距離加1 按照以上的性質實現merge x,y 先選出x,y中比較大的那個 大根堆為例 再拿它的右兒子和另乙個去merge,如果merge出來不符合性質2就swap一下...