专栏文章
数据结构 Trick 之:平衡树有交合并
算法·理论参与者 2已保存评论 2
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @miqh4k4y
- 此快照首次捕获于
- 2025/12/04 04:42 3 个月前
- 此快照最后确认于
- 2025/12/04 04:42 3 个月前
能解决的问题类型
需要将两个值域有交可重集合并的问题。
优缺点
无
思路
这个 Trick 基于 FHQ。
首先,让我们回顾一下 FHQ 的 merge:
CPPint merge(int l, int r) {
if (node[l].randd <= node[r].randd) {
pushdown(l);
node[l].rs = merge(node[l].rs, r);
pushup(l);
return l;
} else {
pushdown(r);
node[r].ls = merge(l, node[l].ls);
pushup(r);
return r;
}
}
我们知道:这个东东只能解决不交合并,但是,我们可以受此启发。
流程
- 找到 小的那个根作为合并之后的树根。
- 将 小的那个树按总树根进行分裂。
- 分裂左边跟总根的左子树合并,右边跟总根的右子树合并
例题与代码
由于其他的都是普通平衡树,就只放这个函数了。
CPPint Merge(int l, int r) {
if (!l || !r) return l | r;
int L, R;
if (node[l].ran <= node[r].ran) {
pushdown(l);
split(r, L, R, node[l].v);
node[l].ls = Merge(node[l].ls, L);
node[l].rs = Merge(node[l].rs, R);
pushup(l);
return l;
} else {
pushdown(r);
split(l, L, R, node[r].v);
node[r].ls = Merge(node[r].ls, L);
node[r].rs = Merge(node[r].rs, R);
pushup(r);
return r;
}
}
相关推荐
评论
共 2 条评论,欢迎与作者交流。
正在加载评论...
那么我们是不是可以将其中一棵树分成两半,分别合并呢?(如下图)
这个合并复杂度几乎