线段树
维护序列的树形数据结构——线段树
面对以下问题luoguP3372,给出一个数列:
(1) 将区间【x,y】内每一个数加上 k
(2) 求出某个区间【x,y】中每一个数的和。
虽然普通方法修改复杂度 O(1) 但是求和的效率却是 O(n)
线段树的思想个人来讲就是归并,线段树所维护的信息必须具有可合并性,个人认为其实现原理过于基础,不做分析。
一些有意思的证明:
对于节点数为 n 深度为 h 的一棵树,其深度可以表示为 ( n + 1 ) 2 + 1 2 + 1 2 . . . \frac{\frac{\frac{(n+1)}{2}+1}{2}+1}{2}... 222(n+1)+1+1... 之 后由于得知这个值永远不会超过 ( n + h ) 2 h \frac{(n+h)}{2^h} 2h(n+h),而 ( n + h ) 2 h ≈ 1 \frac{(n+h)}{2^h}\approx{1} 2h(n+h)≈1 所以解方程得到 h = O(logn) \textup{\textbf{h = O(logn)}} h = O(logn)。
以上的推论在下面的理论中显得格外重要:
结论:线段树的结点的最大编号不会超过 4n-1 \textup{\textbf{4n-1}} 4n-1,其中 n n n 是序列长度。
考虑二叉树的建立方式,根节点为 1,对于一个结点 i i i 建立时左儿子记为 2 i 2i 2i 右儿子记为 2 i + 1 2i+1 2i+