线段树
学习线段树(segment tree):https://www.youtube.com/watch?v=ZBHKZF5w4YU
学习线段树的懒惰传播(lazy propagation):https://www.youtube.com/watch?v=xuoQdt5pHj0
首先简单介绍一下什么是线段树,以及为什么要使用线段树。
假设有一个数组,我们需要对该数组执行如下操作(以下全部假设数组下标从 0 0 0开始):
- 求一个区间 [ l o w , h i g h ] [low, high] [low,high]内的最小值(或者最大值,或者一个区间内元素的和)。
- 修改第 i i i项元素。
如果使用普通的数组,执行第一个操作的时间为 O ( n ) O(n) O(n),执行第二个操作的时间为 O ( 1 ) O(1) O(1)。
而使用线段树,这两个操作的时间都为 O ( log 2 n ) O(\log_2n) O(log2n)。
构造线段树
线段树与堆排序中的堆有一些类似。线段树中的叶子节点为原数组中的元素。假设我们要维护一个求范围和的线段树,那么这些叶子节点的父节点的值为所有子节点的和。
对于一个长度为 n n n的数组,构造一个线段树需要的空间为:
- 假设 n n n为 2 2 2的幂次方,例如 n = 4 n = 4 n=4,那么需要的空间为 2 ∗ n − 1 = 7 2 * n - 1 = 7 2∗n−<