表示学这些东西是为了为学可持久化treap铺垫。
但实际上这是一种很鸡肋的数据结构。

用来解决什么问题?

就是在堆的基础上,支持O(lgn)的合并操作。
解决这个问题的似乎还有个斐波拉契堆,不懂……

数据结构核心

左偏树

这不是一个完全二叉树,它就是一个二叉树。
性质和堆一样,对于小根堆,爸爸都比儿子小。
但它多了一个dist,x节点的dist表示x的后代中没有左或右节点到x的最短距离。
xdist=min(xldist+1,xrdist+1)
xl=NULLxr=NULL,则xdist=0

左偏树有个性质,叫左偏性质:xldist>=xrdist
这个性质很有用,可以使树高小一些,因为合并是在右边进行的。
如果要合并A、B,设Aval<Bval,就让Ar和B合并,继续递归,让合并出来的树变成Ar
回溯的时候,如果不满足左偏性质,就进行交换。最后更新dist。

struct Leftist_Tree
{
    struct Node
    {
        int l,r;
        int val,dist;
    } d[100001];
    int cnt;
    int newnode(int _val)
    {
        d[++cnt].val=_val;
        d[cnt].dist=1;
    }
    int merge(int a,int b)
    {
        if (!a)
            return b;
        if (!b)
            return a;
        if (d[a].val>d[b].val)
            swap(a,b);
        d[a].r=merge(d[a].r,b);
        if (d[d[a].r].dist>d[d[a].l].dist)
            swap(d[a].l,d[a].r);
        d[a].dist=d[d[a].r].dist+1;
        return a;
    }
}

斜堆

和左偏树差不多,但是不需要记录dist值,没有左偏性质,只是在回溯时直接交换左右子树。这就是期望!
虽然比左偏树简单一点,但左偏树比它更优。