码迷,mamicode.com
首页 > 其他好文 > 详细

关于线段树的一些学习笔记——(无限施工中)

时间:2017-12-23 17:10:15      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:log   思考   级别   gpo   直接   时间复杂度   个数   简单的   合成   

  (施工中orz)

  20171223:更新一些关于线段树的基础用法,以及简单的zkw线段树、权值线段树,动态开点线段树,线段树的标记永久化,主席树,可持久化线段树,可持久化线段树的标记永久化(施工中)

  这几天学了学各种姿势的线段树

  什么是线段树呢?请先思考这样一个问题:

  给定一个长度为n的数组,有m次操作,每次操作有如下几种可能:

  1、给ai加上v

  2、给a[L,R]上的每个数加上v

  3、求区间[L,R]上a的最大/小值

  4、求区间[L,R]上∑(i∈[L,R])ai

  5、查询ai的值

  当然,这些操作都可以只用一个数组a进行模拟来完成

  现在我们分析一下复杂度:对于操作1、5来说,每次的时间复杂度为O(1),因为只需要修改或输出数组a[i]的值就好了,但是对于操作2、3、4来说,每次的时间复杂度为O(区间长度)

  在这种情况下,,理论最差情况下的时间复杂度是O(mn)的

  这样的方法显然对于十万及以上级别的数据非常棘手

  因此我们需要一种可以处理较大数据量的数据结构

  这时候树状数组 线段树就来了

  既然区间问题不好处理,那么我们是否能够想到一种查找区间效率较高的算法呢?

  仔细想一下:对于两个区间[l,m],[m+1,r],l<m<r来说,这两个区间我们可以合成为一个区间,即区间[l,r]

  那么我们也可以说,区间[l.r]包含了区间[l,m]和[m+1,r],同时,[l,m],[m+1,r]这两个区间内又包含了其它的区间

  于是我们就可以将区间[1,n]进行不断的细分,最后所有区间的长度都为1

  显然我们可以用树来表示区间之间的从属关系。

  为了方便,我们一般采用二叉树的形式来存储区间,且区间[l,r]的2个儿子节点之间的分界线恰为[l,r]的中点

  也就是说,我们通过树,用二分的方法,间接地将区间进行了细分

  这就是区间树。可以证明,二叉区间树的深度为logn(本文中所有的log均为log2

  那么,在这棵区间树上,如果要查询区间[l,r]的值,那么我们可以对这个区间进行细分,将其化为区间树上的一些点所代表的区间的集合

  因为在区间树上,我们最终将整个区间都划分为了长度为1的区间,那么对于任何区间,都可以在区间树上以点的集合的形式进行表示

  因为当我们在区间树上找到一个区间属于当前要操作的区间时,其从属的区间没有必要进行查找,那么显然在区间树上查询一个区间的值的时间复杂度是log级别的

  因此单点操作的时间复杂度也是log级别的

  这样的话我们就能将单点操作和区间操作的时间复杂度进行均摊,达到log级别

  可以发现,区间树的时间复杂度是非常优秀的

  而大部分情况下线段树就是在二叉区间树上进行操作的数据结构

  那么我们考虑一下以上几种操作的具体事项:

  对于单点操作来说,我们直接递归到对应的叶子结点,然后修改即可

  对于区间修改来说,我们需要通过递归找到所有对应的区间(包括对应区间的子区间),然后进行修改

  对于区间查询来说,只需要找到对应的区间即可

  (施工中orz)

关于线段树的一些学习笔记——(无限施工中)

标签:log   思考   级别   gpo   直接   时间复杂度   个数   简单的   合成   

原文地址:http://www.cnblogs.com/hinanawitenshi/p/8093624.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!