数据结构 线段树
一、区间问题和线段树
有一类区间问题可以抽象成如下模型。
给定包含 n n n 个数的数组 a 1 , a 2 , ⋯ a n a_1, a_2, \cdots a_n a1,a2,⋯an。有两种操作:
- 查询区间 [ l , r ] [l, r] [l,r] 最小的数。
- 修改第 a i a_i ai 为 x x x。
这里,为了解决这个问题,我们介绍一种灵活的数据结构——线段树。
我们用一棵二叉树来表示线段树,线段树中的每个结点都表示一个区间。每个非叶子结点都有左右两棵子树,分别对应区间的 “左半” 和 “右半”。为了方便起见,我们给根结点编号为 1 1 1。对于每个结点,其左结点的编号为 2 i 2i 2i,其右结点的编号为 2 i + 1 2i+1 2i+1。
对于一个结点,如果其表示的区间为 [ l , r ] [l, r] [l,r]。分情况如果 l = r l = r l=r,那么这个是一个叶子结点。否则令 m i d = ⌊ l + r 2 ⌋ mid = \lfloor \frac{l+r}{2} \rfloor mid=⌊2l+r