启发式合并&线段树合并&treap合并

来源:互联网 发布:js模拟按键 编辑:程序博客网 时间:2024/04/27 23:37

启发式合并

​ 有n个集合,每次让你合并两个集合,或询问一个集合中是否存在某个元素。

​ 我们可以用平衡树/set维护集合。

​ 对于合并两个A,B,如果|A|<|B|,那么我们就把A中的每个元素暴力加到B中,否则就把B中的元素暴力加到A中。

​ 对于一次把A中的每个元素暴力加到B中的操作,|A|会变成|A|+|B|,也就是说大小至少会翻倍,所以一个元素最多被暴力插入logn次。每次插入的时间复杂度是O(logn),所以总的时间复杂度是O(nlog2n)

线段树合并

​ 如果两棵线段树有一颗为空,就直接返回另一棵。

​ 否则把x的左儿子和y的左儿子合并在一起,作为x的左儿子,然后把x的右儿子和y的右儿子合并在一起,作为x的右儿子。

​ 设值域为[1,n],总的点数为m

​ 对于线段树上一个区间,这个区间内所有点的值和为s,那么全部合并结束后这个区间最多被经过O(s)次,所以时间复杂度是O(s)=O(mlogn)

treap合并

​ 对于两个点x,y,把优先级较小的那个点(假设是x)作为根,然后把另外一棵树y按照vx剖开,两边递归下去合并。

​ 时间复杂度不会证,反正把大小为n,m(nm)的两棵treap合并是O(nlogmn)的。所以总的时间复杂度是O(nlogn)的。

​ 论文在资源收集那篇博客里面有。

原创粉丝点击