启发式合并 splay合并 线段树合并基础
Gold is everywhen! - somebody
启发式合并
将小的集合一个个插入到大的集合。
每次新集合大小至少比小集合大一倍,因此每个元素最多合并\(\log n\)次,总复杂度为\(n\log n\) × 插入复杂度。
splay合并
将小的splay按中序遍历一个个插入到大的splay。
可证明复杂度为\(O(n\log n)\)。
没什么特殊的应用。
线段树合并
int merge(int x, int y, int l, int r) {
if(!~x) return y;
if(!~y) return x;
if(l == r) {
info[x] = combine_leaf(info[x], info[y]);
return x;
}
int mid = l + r >> 1;
ls[x] = merge(ls[x], ls[y], l, mid);
rs[x] = merge(rs[x], rs[y], mid+1, r);
info[x] = combine(info[ls[x]], info[rs[x]]);
return x;
}
可证明复杂度为\(O(n\log n)\)。
线段树合并和splay合并能做的题很像,线段树合并常数更小。