从刘汝佳的书中得知,“这种数据结构在学术界没有统一的术语,但线段树是最常见的叫法。其他叫法包括区间树(interval tree)、范围树(range tree)等,但这些属于在特定的场合(如计算几何)中有着特殊的意义”。怎么叫看读者的心情,以下统一用线段树称呼。
线段树是一棵二叉树,它的左右儿子也都是一棵线段树。(定义)
线段树也叫区间树,为什么叫它区间树呢?因为线段树是一种基于区间的数据结构。
线段树的每个节点代表一个区间 [L,R],其中存储的是这个区间的特定值。
例如RMQ(Range Minimum/Maximum Query,范围最大/最小值)问题,给出n个元素的数组,查询任意区间内的元素最大/最小值。
这个问题就是基于区间查询的,需要用到线段树,而它节点中存储的特定值就是所代表区间的最大/最小值。
某个节点代表区间 [L,R],其两个儿子节点代表区间分别为 [L,mid],[mid+1,R]( mid = (L+R)/2 )。
1、点修改
在[L,R]中修改[LL,RR](LL=RR)的时候有两种情况。
第一种,[LL,RR]被[L,mid]包含,此时直接在[L,mid]中修改[LL,RR]
第二种,[LL,RR]被[mid+1,R]包含,此时直接在[mid+1,R]中修改[LL,RR](同理)
然后递归更新父亲。
不用考虑被截断(因为只是一个点)。
2、区间修改
在[L,R]中修改[LL,RR](LL<RR)的时候有三种情况。
第一种,[LL,RR]被[L,mid]包含,此时直接在[L,mid]中修改[LL,RR]
第二种,[LL,RR]被[mid+1,R]包含,此时直接在[mid+1,R]中修改[LL,RR](同理)
第三种,较复杂的一种,[LL,RR]被mid从中截断,此时在[L,mid]中修改[LL,mid],在[mid+1,R]中修改[mid+1,RR],然后将两个查询得到的结果进行update,递归更新父亲。
这样便处理完了修改。
RMQ问题,存储值,优化DP。
两者在复杂度上同级, 但是树状数组的常数明显优于线段树, 其编程复杂度也远小于线段树.
树状数组的作用被线段树完全涵盖, 凡是可以使用树状数组解决的问题, 使用线段树一定可以解决, 但是线段树能够解决的问题树状数组未必能够解决.
树状数组的突出特点是其编程的极端简洁性, 使用lowbit技术可以在很短的几步操作中完成树状数组的核心操作,与之相关的便是其代码效率远高于线段树。
另外,当问题推广到高维情形时高维树状数组有高维线段树所无法企及的常数优势。
Freecode : www.cnblogs.com/yym2013
原文:http://www.cnblogs.com/yym2013/p/3703763.html