一、什么是线段树
线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶节点。
对于线段树中的每一个非叶子节点[a, b], 它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/ 2+1,b].
使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(lonN)。
线段树的思想和分治思想很相像。
线段树的每一个节点都储存着一段区间 [L...R]的信息,其叶子节点,也就是最后的节点L=R。
它的大致思想是:将一段大区间平均地划分为2个小区间,每一个小区间都再平均分成2个更小区间......以此类推,直到每个区间的L等于R(这样此区间仅包含一个节点的信息,无法被划分。即最后的叶子节点)。
通过对这些区间进行修改、查询,来实现对大区间的修改、查询。这样一来,每次修改,查询的时间复杂度都只为O(log2n)。
但是,可以用线段树维护的问题必须满足区间加法,否则是不可能将大问题划分成子问题来解决的。
什么是区间加法:一个问题满足区间加法,仅当对于区间[L,R]的问题的答案可以由[L, M] 和 [M+1,R]的答案合并得到。
二、线段树的基本内容
不要觉得线段树只是为了解决区间问题的数据结构,事实上,是线段树多用于解决区间问题,并不是线段树只能解决区间问题,首先,我们得先明白几件事情。
线段树主要是把一段大区间平均地划分成两段小区间进行维护,再用小区间的值来更新大区间。
这样既能保护正确性,又能使时间保持在log级别(因为这棵线段树是平衡的)。