左偏树的特点——可并堆
本质上是一个二叉(最小)堆。
const int N = 2e5 + 10;
struct node
{
int v, dist, lson, rson;
} tr[N];
通过维护dist(距离最近的“叶子节点”(并不严谨)的距离)来实现log级的合并
题目需要的操作也大多数是合并两个集合+取集合最值进行操作
核心函数merge:
int merge(int x, int y)//将下x,y两颗子树合并,返回root
{
if (!x || !y)
return x + y; //如果有一棵树(x)是空的,返回另一边(y)
if (cmp(y, x))
swap(y, x);
tr[x].rson = merge(tr[x].rson, y); //递归合并
if (tr[tr[x].lson].dist > tr[tr[x].lson].dist)
swap(tr[x].lson, tr[x].rson); //合并完了要保证左偏
tr[x].dist = tr[tr[x].lson].dist + 1;
return x;
}
未完待续