左偏树+笛卡尔树

左偏树/可并堆

外部点:左儿子或右儿子为空的节点
\(dis_{x}\):距离 \(x\) 最近的外部点
性质:

  1. 小根堆
    就是要维护这个的
  2. 距离为 \(n\) 的左偏树至少有 \(2^{n+1}-1\) 个节点
    否则必然会有一个节点距离 \(<n\)
  3. \(n\) 个点的左偏树树高为 \(log\)
    维护保证了,结合上面理解。
    后来周邦在课上拷打我了,这该怎么办呢?
    我们发现 \(merge\) 是和 \(dis\) 相关的,所以就做完了
    合并:
    正常堆合并参考 fhq 的 \(merge\),随机选一个儿子合并,期望是 \(log\)
    左偏树中左儿子距离>右儿子距离,那么将右儿子合并
    然后挑一个 \(dis\) 小的儿子并上去

支持操作:
合并,删除最小数(合并左右子树),求最小值

int merg(int x,int y){
    int xi=get(x),yi=get(y);
    push_down(xi),push_down(yi);
    return fa[xi]=fa[yi]=merge(xi,yi);
}
int del(int x){
    x=get(x);
    push_down(x);
    return fa[x]=fa[son[x][0]]=fa[son[x][1]]=merge(son[x][0],son[x][1]);
}

笛卡尔树

我们的单调栈维护的是从根的右链,然后注意一下就可以了。

性质

你的脑子好像不是特别好
\(lca(l,r)\) 的值是 \([l,r]\) 的最大值。
考虑证明,首先 \(lca(l,r)\) 上面的点不可能成为最大值,因为 \(l,r\) 都在上面那个点的左边或者右边(根据按照下标的二叉搜索树的性质)然后 \(lca(l,r)\) 一定在 \(l\)\(r\) 之间,怎么证明。很简单啊,\(l,r\)分别在 \(lca(l,r)\) 的左右两棵子树中

posted @ 2025-07-14 08:10  wuhupai  阅读(7)  评论(0)    收藏  举报