文艺出题人啊……
第一眼看起来是个动态树,但是出题人给出了一个更简单的做法,仅需要线段树就可以解决。
首先我们从平衡树的定义开始分析:
众所周知平衡树是一种特殊的 BST,而用平衡树维护序列时,它的中序遍历就是这个序列。
以及,平衡树的旋转是维护平衡的一个策略,显然它的中序遍历不会改变。
于是又发现一个性质:中序遍历时,一棵子树是连续的。
所以我们用前缀和维护中序遍历的区间和,用线段树维护中序遍历的区间积。
旋转只会改变两棵子树的区间,可以在常数复杂度内维护。
Orz 了 LZW 大佬的代码发现可以直接用结点的中序遍历减去左儿子的 size 得到区间左端点,右端点类似。
代码:
1 |
|