吉司机线段树的复杂度证明

请注意,本文只有复杂度证明,没有算法简介,如果您要学习该算法,请移步 https://oi-wiki.org/ds/seg-beats/

以下所有说明均以 区间取min 为例。

单点修改,区间取最值

时间复杂度:\(O(n\log n + m \log n )\)

设计每个点的势能函数 \(\phi(u)\) 为其管辖区间内不同值的数量。

比如 \([1,2,4,1,2]\) 就是 \(3\)

我们发现影响复杂度的关键在于当 \(x<max_2(u)<max_1(u)\) 时的暴力向下递归。

发现每当一个点被暴力向下递归一次,他的 \(\phi(u)\) 就会减少 \(1\) ,(很明显因为至少 \(max_1\)\(max_2\) 都会变为 \(x\))。

分析一下总势能。

初始势能:\(O(n\log n)\) (最坏所有初始的数均不一样)

单点修改:\(O(\log n)\)(因为最多影响一条链)

故复杂度为 \(O(n\log n + m \log n )\)

区间修改,区间取最值

时间复杂度:\(O(n\log n + m \log^2 n )\)

设计每个点的势能函数 \(\phi(u)\)\([max_1(u)\ne max_1(fa(u))]\)

比如图中最左边的叶子的 \(\phi(u)\) 就是 \(1\) ,第三个叶子就是 \(0\)

同样的,影响复杂度的关键在于当 \(x<max_2(u)<max_1(u)\) 时的暴力向下递归。

发现每当一个点被暴力向下递归一次,他某个后代的 \(\phi(u)\) 就会减少 \(1\) ,(因为存在 \(max_1(u)\)\(max_2(u)\) 就说明有一个后代的 \(max_1(v)\)\(max_2(u)\) ,那个点就和父亲不一样,然后现在那个点要被抹平)。

所以 \(1\) 的势能可以带来 \(O(\log n)\) 的复杂度(因为最差是一整条链服务一个点)。

分析一下总势能。

初始势能:\(O(n)\) (最坏所有点和父亲不一样)

区间修改:\(O(\log n)\)(因为只会影响 \(O(\log n)\) 个点)

故复杂度为 \(O(n\log n + m \log^2 n)\)

posted @ 2026-03-21 21:44  cute_yinqf  阅读(3)  评论(0)    收藏  举报