关于线段树合并的时间复杂度

线段树合并的时间复杂度一直是个玄学东西,这里稍微证明一下。
设原先需要合并的点的个数为 \(k\) ,初始势能为 \(3*k\)
定义势能函数 \(\Phi=3\times 参与合并的全部点的个数\)
当两颗线段树合并时,设其重合的点个数为 \(sz\)
而点重合时便会对其左右儿子继续合并,接下来参与合并的点个数将减 \(1\)
没重合的点会直接返回,势能不变。
然而被遍历到的不重合的点的个数是 \(\leq 2*sz\) 的,
所以整个合并过程时间复杂度为 \(O(3*sz)\) 的,
故其摊还时间为 \(O(3*sz+\Delta \Phi)=O(3*sz-3*sz)=O(0)\)
而最终合并完点的个数 \(\leq\) 初始点的个数,且点至多为 \(O(2*n)\) 个( \(n\) 代表线段树的下标大小)
所以时间复杂度为 \(O(3*k-2*n)\leq O(3*k)=O(k)\)
实际中 \(k\) 一般为 \(O(n*log(n))\),跑 \(10^5\) 的数据还是很轻松的,但常数和 \(splay\) 有得一比。

posted @ 2021-08-02 18:13  Y_B_X  阅读(478)  评论(0编辑  收藏  举报