线段树第二弹(区间更新)



上篇文章,我们介绍了线段树的基本概念和单点更新、区间查询,今天,我们来接着上次的线段树问题继续深入研究。在解决线段树问题的过程中,我们会遇到要求修改区间中某一元素值的问题,当然也可能会遇到要求修改一段子区间所有值的问题--即区间更新问题。回忆一下上篇文章单点更新的方法是,由叶节点逐级向上进行更新,此时更新一个节点值的时间复杂度为o(log n),(点击链接了解详情:线段树+RMQ问题第二弹),那么以这样的处理效率来进行区间更新结果会怎样?现在假设待更新区间数据的规模为 n ,那么就需要进行 n 次单点更新,也就意味着处理的时间复杂度为 o(n* log n),这样的时间复杂度其实还是可以接受的,但是,在实际生活中问题怎么可能那么简单就给一个区间呢?这样岂不是让做题的人太舒服了。所以,再假设待查询的区间个数也为 n ,这时候,时间复杂度就变成了 o(n*n*log n),如果这个 n 的值再大一点。。。你敢继续往下想吗?

我大概是不敢了,所以现在需要尝试找一种快捷的方法或者在现有的方法基础上进行优化。

通常情况下,如果时间复杂度过高,我们就会考虑牺牲空间来换取时间,利用线段树来解决区间最值查询问题的思路也是如此,那么在区间更新的问题上,我们应该如何合理利用空间换取时间呢?经过分析可以发现,在区间更新的问题中,我们要做的无非就是取一个区间的信息,接着获取更新的方式,最后定位范围进行更新。如果待更新区间中每个元素的更新方式都不同,那没有办法,我们只能因元素而异,对症下药,但如果待更新区间所有元素都遵循统一的更新规则,例如均加上某个常数,那处理起来就会有一致性,我们就可以以此为切入点进行研究。

我们都知道,元素更新问题一般会伴随着查询问题,如果更新与否对当前面对的所有问题不会造成影响,这时候我们可以借鉴赊账的原理,对需要更新但当前不需要查询的区间暂不更新,并把这笔账记下,待需要查询的时候,将这笔账偿清,这样也并不影响查询过程的正确性。有人喜欢赊账,觉得这年头,花呗上没点旧账都不叫生活,但有的人却不喜欢这种透支未来的生活方式。这里我想说在做题的过程中赊点帐还是无伤大雅的,重要的是,这种赊账的思想用在这里还真是恰到好处呢,不信你就往下看。在继续之前,我大胆的猜测一下,会不会有人因为看了我这篇文章,到实践中检验真理,兜里有钱也去花呗上赊点帐玩玩。

现实中我们要赊账打开支付宝就可以了,那么在解决区间更新的问题中,我们如何赊账呢?方法很简单,我们需要牺牲空间用来记录线段树上的每个节点是否需要更新,如果需要更新,需要更新的规则是什么。以给区间上的每个元素加一个值 x 为例,如果该节点所表示的区间需要更新,那我们就可以将对应的赊账标记记为 x ,当需要查询该区间时,对该区间进行更新,并清除赊账标记,如果该节点所表示的区间不需要更新,对应的赊账标记记为 0 。这样做的好处就在于,省去了更新无需查询区间的值,如果一次查询的过程中,只更新不查询的操作比较多,那可以料想到,节省的时间将是不可估量的。

总是赊账这么叫,看起来好 low ,其实,这个方法有个高大上的名字--Lazy 思想,赊账标记也就叫做——Lazy Tag 。

这个想法浅显易懂,很容易就想明白了,但其发挥的作用却是无法估量的,正所谓大道至简,有时候也许就是这样浅显的道理、细微的改进效果就可以非常显著,还有时候比别人再多往前迈进一小步,就能看见另一番天地。无论是钻研问题还是生活,这个道理都同样适用。

接下来我给大家展示一下核心代码部分,希望大家看了代码能对此有更加深入的体会。

由于上篇文章中,我们介绍的线段树存储的是区间最小值,今天就以之前的假设为基础,深入研究。



以上就是今天的代码分享,发现其中有错误或者有更简洁方法的朋友可以在下方留言区留言,或者点击作者名片添加微信好友私聊,不胜感激。

还没关注公众号的朋友可以长按下方图片识别二维码关注呦。

长按二维码识别关注



代码的网页版可以打开网页http://paste.ubuntu.com/25534094/。

时间: 2024-10-29 19:07:15

线段树第二弹(区间更新)的相关文章

HDOJ--4893--Wow! Such Sequence!【线段树+单点、区间更新】

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893 题意:给你一个长度n的数列,初始都为0,有三种操作,第一种给第k个位置的数加d,第二种是查询区间 [l , r] 的总和,第三种是使区间 [l , r] 的值改为离它最近的那个斐波那契数的值. 我刚开始用sum数组存储节点的值,第三种操作是个区间更新,但是区间更新的值不一样,我就想当然的搜到最底部的节点来处理更新,果断T了.后来想了想,其实可以在节点上再加一个信息,就是这个值下次进行第三种操作要变

codevs 1082 线段树练习 3 区间更新+延迟标记

题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述 Input Description 第一行一个正整数n,接下来n行n个整数, 再接下来一个正整数Q,每行表示操作的个数, 如果第一个数是1,后接3个正整数, 表示在区间[a,b]内每个数增加X,如果是2, 表示操作2询问区间[a,b]的和是多少. pascal选手请不要使用readln读入 输出描述 Output Description 对于每个询问输出一行

codevs 1081 线段树练习 2 区间更新 单点查询 无lazy

题目描述 Description 给你N个数,有两种操作 1:给区间[a,b]的所有数都增加X 2:询问第i个数是什么? 输入描述 Input Description 第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数.如果第一个数是1,后接3个正整数a,b,X,表示在区间[a,b]内每个数增加X,如果是2,后面跟1个整数i, 表示询问第i个位置的数是多少. 输出描述 Output Description 对于每个询问输出一行一个答案 样例输

树状数组区间更新

在今天的文章开始之前,给大家提一个建议,由于线段树和树状数组这两个结构的分析有很多联系,因此,建议没有看前几篇文章的朋友一定需要了解一下前面的内容.链接如下: 线段树+RMQ问题第二弹 线段树第二弹(区间更新) 树状数组(Binary Indexed Tree,BIT) 上篇文章我们讨论了树状数组的基本结构以及它最擅长的两个功能:单点更新和区间求和,今天,我们来接着上一篇文章的内容继续深入研究.上篇文章我们是将树状数组和线段树进行对比讲解的,既然线段树的章节我们介绍了区间求和.区间最值.单点更新

hdu 1556:Color the ball(第二类树状数组 —— 区间更新,点求和)

Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8984    Accepted Submission(s): 4594 Problem Description N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球

hdu 4893 Wow! Such Sequence!(线段树功能:单点更新,区间更新相邻较小斐波那契数)

转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893 --------------------------------------------------------------------------------------------------------------------------------------------

NYOJ 1068 ST(线段树之 成段更新+区间求和)

ST 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 描述 "麻雀"lengdan用随机数生成了后台数据,但是笨笨的他被妹纸的问题给难住了... 已知lengdan生成了N(1=<N<=10005)个随机整数,妹子对这些数可能有以下几种操作或询问: 1,A a b c 表示给区间a到b内每个数都加上c: 2,S a b  表示输出区间a到b内的和: 3,Q a b 表示区间a到b内的奇数的个数: 为了使妹纸不口渴,所以我们决定妹纸的询问次数少一点,即

POJ 3468-A Simple Problem with Integers(线段树:成段更新,区间求和)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 62228   Accepted: 19058 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

POJ 3468 A Simple Problem with Integers(线段树模板之区间增减更新 区间求和查询)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 140120   Accepted: 43425 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type o