线段树专题
给出数列[1 4 2 3],求给定区间的最大值
例:query(0,1) = 4 query(2,3) = 3 query(0,3) = 4
一道题可不可以用线段树来做,基本是看这道题的操作有没有区间的性质。也就是在一个区间上的操作是否可以转化为两个子区间上的操作。
从这题可以看出
区间(a,b)的最大值和区间(b,c)的最大值中
取较大的就是区间(a,c)的最大值
很明显可以看出这个操作是具有区间的性质。
求区间的和,积,最大值,最match小值,gcd等
以当前结点的值作为结点处理,比如给出N个数,再给一个数,问比这个数大的有多少个(当然,用树状数组可以很好的处理,但有修改时,线段树就会方便很多)
区间加减同一个值,或者区间同时赋一个值(在面试中,通常不会问到,算法竞赛中会经常用到)
区间划分大概就是上述的区间划分。可以看出每次都将区间的长度一分为二,数列长度为n,所以线段树的高度是log(n),这是很多高效操作的基础。
上述的区间存储的只是区间的左右边界。我们可以将区间的最大值加入进来。
区间的第三维就是区间的最大值
加这一维的时候只需要在建完了左右区间之后,根据左右区间的最大值来更新当前区间的最大值即可。
因为每次将区间的长度一分为二,所有创造的节点个数为
n + 1/2 * n + 1/4 * n + 1/8 * n + ...
= (1 + 1/2 + 1/4 + 1/8 + ...) * n
= 2n
所以构造线段树的时间复杂度和空间复杂度都为O(n)
给定一个区间,要求区间中最大的值。
线段树的区间查询操作就是将当前区间分解为较小的子区间,然后由子区间的最大值就可以快速得到需要查询区间的最大值。
query(1,3) = max(query(1,1),query(2,3)) = max(4,3) = 4
上述例子将(1,3)区间分为了(1,1)和(2,3)两个区间,因为(1,1)和(2,3)区间的最大值事先已经记录好了,所以直接拿来用就可以了。
考虑长度为16的序列构造成的线段树,区间(0,15)。查询区间(1,14)。
第一层会查询 (1,7) (8,15)
第二层会查询 (1,3) (4,7) (8,11) (12,14)
第三层会查询 (1,1) (2,3) (12,13) (14,14)
第四层会查询 (1,1) (14,14)
因为是连续的,中间那部分会直接算出来,然后两边的两端继续往下,还是4个区间。
因为线段树的高度为log(n),所以查询的时间复杂度为O(log(n))
如何把这种变化体现到线段树中去?
例如,将序列中的第4个点更新为5,要变动3个区间中的值,分别为[3,3],[2,3],[0,3]
可以这样想,改动一个节点,与这个节点对应的叶子节点需要变动。因为叶子节点的值的改变可能影响到父亲节点,然后叶子节点的父亲节点也可能需要变动。
所以需要从叶子节点一路走到根节点,去更新线段树上的值。因为线段树的高度为log(n),所以更新序列中一个节点的复杂度为log(n)。
如果需要区间的最小值或者区间的和。和构造的时候同理。
http://www.lintcode.com/zh-cn/problem/segment-tree-build/
http://www.lintcode.com/zh-cn/problem/segment-tree-build-ii/
http://www.lintcode.com/zh-cn/problem/segment-tree-modify/
http://www.lintcode.com/zh-cn/problem/segment-tree-query/
http://www.lintcode.com/zh-cn/problem/segment-tree-query-ii/
http://www.lintcode.com/zh-cn/problem/interval-minimum-number/
http://www.lintcode.com/zh-cn/problem/interval-sum/
http://www.lintcode.com/zh-cn/problem/interval-sum-ii/
http://www.lintcode.com/zh-cn/problem/count-of-smaller-number/
http://www.lintcode.com/zh-cn/problem/count-of-smaller-number-before-itself/
免费直播视频讲座
OOD 设计 & 面试题解析
什么是 OOD?
如何设计 OOD?
OOD 五个设计要点
OOD 两大 Design Pattern
北京时间:3月30日 10:00-12:30(周四a.m.)
美西时间:3月29日 19:00-20:30(周三)
美东时间:3月29日 22:00-23:30pm(周三)
快登陆官网或点击阅读全文报名吧!
本文仅代表个人观点,版权所有,谢绝转载