启发式合并
有\(n\)个集合,每次让你合并两个集合,或询问一个集合中是否存在某个元素。
? 我们可以用平衡树/set维护集合。
? 对于合并两个\(A,B\),如果\(|A|<|B|\),那么我们就把\(A\)中的每个元素暴力加到\(B\)中,否则就把\(B\)中的元素暴力加到\(A\)中。
? 对于一次把\(A\)中的每个元素暴力加到\(B\)中的操作,\(|A|\)会变成\(|A|+|B|\),也就是说大小至少会翻倍,所以一个元素最多被暴力插入\(\log n\)次。每次插入的时间复杂度是\(O(\log n)\),所以总的时间复杂度是\(O(n\log^2n)\)。
线段树合并
? 如果两棵线段树有一颗为空,就直接返回另一棵。
? 否则把\(x\)的左儿子和\(y\)的左儿子合并在一起,作为\(x\)的左儿子,然后把\(x\)的右儿子和\(y\)的右儿子合并在一起,作为\(x\)的右儿子。
? 设值域为\([1,m]\),总的点数为\(n\)。
好像要\(m\)和\(n\)同阶
? 对于线段树上一个区间,这个区间内所有点的值和为\(s\),那么全部合并结束后这个区间最多被经过\(O(s)\)次,所以时间复杂度是\(O(\sum s)=O(n \log n)\)。
treap合并
? 对于两个点\(x,y\),把优先级较小的那个点(假设是\(x\))作为根,然后把另外一棵树\(y\)按照\(v_x\)剖开,两边递归下去合并。
? 时间复杂度不会证,反正把大小为\(n,m(n\leq m)\)的两棵treap合并是\(O(n\log\frac{m}{n})\)的。所以总的时间复杂度是\(O(n\log n)\)的。
论文在资源收集那篇博客里面有。
splay合并
听说是把小的那棵splay按中序遍历插到大的那棵splay里面。
听说时间复杂度是\(O(n\log n)\)的。
好像和Dynamic Finger Theorem有关
原文地址:https://www.cnblogs.com/ywwyww/p/8510016.html