标签:
线段树/区间树是一种非常常用的对区间数据进行操作的数据结构。
线段树是一棵二叉树(但不一定是完全二叉树!),它的每个节点均代表一个区间,且父节点代表的区间为左右子节点代表的区间之和。特别的,根节点代表的区间为所有节点代表区间之和,各个叶节点代表区间为单个点(即长度为1的区间)。
树中的每一个结点表示了一个区间[a,b]。 a,b通常是整数。每一个叶子节点表示了一个单位区间(长度为1)。对于每一个非叶结点所表示的结点[a,b],其左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b](除法去尾取整)。
如下图为区间[1, 9]的线段树:
要用线段树解决区间问题,首先需要将区间对应到线段树的节点上。这就需要进行在线段树上进行区间分解。
(1)如果有某个节点代表的区间完全属于待分解区间,则该节点为“终止”节点,不再继续向下分解;
(2)所有“终止”节点所代表的区间都不重叠,且加在一起就恰好等于整个待分解区间;
(3)区间分解时,每层最多2个“终止”节点,所以“终止”节点的总数也是 log(n)量级的
(1)单点更新
每次对区间内的一个点进行更新,更新操作需要递归到叶节点进行操作。在向下递归的过程中,沿途经过的所有节点都要进行修改。
(2)成段更新
简单的说明:成段更新需要用到延迟标记(或者说懒惰标记),简单来说就是每次更新的时候 不要更新到底,用延迟标记使得更新延迟到下次需要更新or询问到的时候。 延迟标记的意思是:这个区间的左右儿子都需要被更新,但是当前区间已经更新了。
(3)区间合并
区间合并是在线段树查询的时候,对当前区间的左右儿子进行合并。
(4)扫描线
有几篇总结很好的博客,便于查找,列在下面:
线段树总结1
线段树总结2
标签:
原文地址:http://www.cnblogs.com/gtarcoder/p/4786734.html