2018暑假集训第四周感想

自古难题多出树,先来高数都线段ヽ(ー_ー)ノ

这周的专题只有一个线段树,然而这棵树一点都不好爬,涉及到的东西比较多,只能先简单总结一下( ̄ー ̄)

像问1 2 3 4 5 6 7 8 9 10这样一个数列的任意区间的和,想必大家都知道,直接前缀和相减就好了,但是再加几个操作,像是给任意区间每一个数加上一个值,或责任意一个数加上一个值,再询问区间和,那该怎么做呢[・_・?]

还像之前那样解决,大数据下,明显会超时,这时候就需要线段树来解决了,线段树的主体思想就是二分,并且可以对区间操作,大大减少了时间复杂度,不过线段树太厉害了,应用太多了,学不过来啊(╥╯^╰╥)

那该怎么操作呢,首先我们得建树,还是之前的例子,我们就可以把它分成一棵二叉树,每个节点保存它的区间范围,和一些值,比如我们在这里我们, 就保存他们的前缀和,可以用递归的方式建树

                                                                                 【1,10】  55

                                         【1,5】  15                                                                    【6,10】 40

                      【1,3】  6                      【4,5】   9                            【6,8】 21                            【9,10】19

          【1.2】3       【3,3】3    【4,4】 4     【5,5】 5       【6,7】13       【8,8】 8        【9,9】 9      【10,10】10

【1,1】1      【2,2】 2                                             【6,6】6       【7,7】7

粗糙的一棵树。。。很明显递归的终点是叶子区间,也就是区间的范围左等于右,然后回溯,每个区间的前缀和就等于它左右子区间的之和,怎么表示区间的编号呢,二叉树嘛,就二分。(〃'▽'〃)

像[【1,10】这个第一个区间,我们给它的编号就是1,然后它的左子区间就是2*1=2,右子区间就是2*1+1=3,所以编号id的区间,左子区间编号2*id,右子区间编号2*id+1,自己拿纸笔模拟下建树过程还是很好理解的(~ ̄▽ ̄)~ 

所以当询问区间和是就是一个区间查询,看一下所查询的区间包含有哪些区间,然后那些区间的和加起来就是答案,而询问某一个数的值也就是单点查询,这时就是查询到叶子节点(๑*◡*๑)

同样的就是区间修改和单点修改,单点修改就是一直找到叶子区间然后修改,而区间修改有个小技巧就是懒标记,也就是“偷懒”,当要修改某个区间每个数的值的时候,直接在这个区间操作,当需要时再把标记传到子区间(*´゚∀゚`)ノ 

例如,我们要个【1,10】这个区间每个数加2,我们可以就在【1,10】这个区间的前缀和里直接加上20,然后区间的标记从0加上2,就不需要每次都到【1,1】【2,2】...这些区间里加2,那什么时候标记下传呢⊙(・◇・)?

再来,比如先给【1,10】这个区间每个数加2,然后这时要【1,5】这个区间每个数再加2,我们就需要先把【1,10】区间的标记传到子区间,然后再执行【1,5】区间的再加2操作,可以拿纸笔模拟,模拟真是个学习的好办法,调试也是( ̄▽ ̄)/

和懒标记有关的还有多标记的标记次序问题,不过我还没怎么学,已经线段树的扫描线,离线处理,建图等等,这些要学要学〒▽〒

最后就是简单讲讲离散化和dfs序,离散化就是像题目给的范围不是很大,数却很大我们就是可以把他们离散化,比如1 10 100 100 1000我们可以离散成1 2 3 4,这样区间范围就小了,就可以建树了,具体怎么离散得具体问题具体分析,名句啊 ̄▽ ̄

而dfs序就是把一些有关的点归为一个连续的区间,而这个区间范围就是dfs遍历每个点时的范围,这样对某些点操作,就是对这个点的区间操作,线段树线段树( ̄. ̄)

线段树最主要的还是去想到用它,起到一个优化的效果,繁化简,唉,真是说起来容易,做起来就是红红火火wa声一片红T^T

还有最后一周,加油(^^)人(^^ )ノ

posted @ 2018-08-13 14:52  新之守护者  阅读(115)  评论(0)    收藏  举报