解题报告-论对“线段树思想”的新理解
一晚上刷了两个线段树知识点,也是见识到了线段树世界的博大精深。
我们发现无论怎么写线段树,大体框架都是一样的。那么为什么有那么多种线段树呢?
一个是线段树标记的不同。在李超线段树中,每个结点维护的是当前结点最上面那条线的编号,于是更新的时候不能只更新一个点,要更新整个区间,这就决定了其 addtag
方式的独特。而在吉司机线段树中,由于要维护很多信息,所以每个信息 pushup
和 pushdown
的方式会有点不一样,这是一点。
第二个就是很重要的一点,线段树的分治思想。我们想想在最朴素的线段树中,当我们发现当前处理的区间 \([l,r]\) 不完全包含于更新或查询的区间 \([L,R]\) 的时候,我们就会把这个问题向左儿子和右儿子分治。这是最朴素的限制:区间范围的限制。
当然,在很多题中,一个区间范围的限制是远远不够的,我们甚至可能受到我们所维护的信息的限制。比如在吉司机线段树中,如果我们要对区间取 \(\min\) 结果发现要取 \(\min\) 的值小于区间次大值,我们肯定是无法待在当前结点就把区间问题处理了。那怎么办呢?
记住一个定律:当你推了很久的公式,发现无论如何加 \(\text{tag}\) 都无法维护当前结点的信息的时候,直接往左右儿子递归。当我们已经记录了足够多的信息,并且不能仅在当前结点就处理区间问题的时候,就相当于当前结点的条件不够,要往左右儿子递归。再不济,递归到底层结点也是可以解决问题的,而往往我们不用递归到底层。
吉司机线段树就是这样分治思想的一个典型范例,而李超线段树也是一样的。一个区间中要更新的一条线段加到这个区间的时候,原来这个区间里有一堆线段,除非这条线段在所有之前的线段之上,你并不能知道哪些该被更新哪些不该被更新,这个时候就要递归到左右子树中加 \(\text{tag}\)。这也就是李超线段树时间复杂度 \(O(n \log^2 n)\) 的原因:线段树本身是 \(O(n \log n)\) 的,但是加 \(\text{tag}\) 是运用了线段树的分治思想,所以多了一个 \(\log\)。
标签:结点,递归,线段,更新,解题,论对,区间,树中 From: https://www.cnblogs.com/KarmaticEnding/p/18673733