线段树是一种能实现$O(\log n + k)$的时间内对一个区间的数进行更新,和维护区间的和以及最大最小值的数据结构,相信大家对此都有一点了解。
而学习线段树时较难理解的就是所谓的“懒标签”,本文就尽量用浅(晦)显(涩)易(难)懂的方式来介绍其在区间查改中的作用,原理,和实现。
本文有不少图解,是我用ppt画的,可能有点丑QAQ。
作用
在线段树中,以$O(\log n)$的时间实现单点修改是十分容易的,只需要一路从父亲回溯并同时更新,一直到根节点停止,过程大致如下。
而如果对于区间更新的话,如果更新区间内的每个节点都回溯到根并更新一次的话,那么复杂度就会降到$O(m \times \log n)$(m是修改区间的长度)。那么这时候就需要引入本文的“说明对象”——懒标记了。
原理
如果我们将懒标签理解为一种“欠条”,则会更加好懂一些。
懒标记起到的效果就是:对于每个更新的操作,从根节点开始向下分解区间,直到将这一区间分为数个不可分解的节点(注意不是叶子节点),然后在这些节点上做个标记,表示“我的每个孙子都挣了k元钱!只是我太懒了,等待会查询操作来了我再分给泥萌吧!”于是该节点记录的的钱财总数(他下面叶子节点的钱财)就加上了$k \times 他下面叶子结点的数量$。
接下来是高清无码图解:
而查询的操作则和原来的单点修改时的查询操作类似,不过区别在于每次查到一个节点时,都要让这个节点将其欠的“债务”向子孙还清。
实现
贴代码(这些代码粘上来就相当于大半个线段树模板了吧):
|
|