解题报告-论对“线段树思想”的新理解

解题报告-论对“线段树思想”的新理解

一晚上刷了两个线段树知识点,也是见识到了线段树世界的博大精深。

我们发现无论怎么写线段树,大体框架都是一样的。那么为什么有那么多种线段树呢?

一个是线段树标记的不同。在李超线段树中,每个结点维护的是当前结点最上面那条线的编号,于是更新的时候不能只更新一个点,要更新整个区间,这就决定了其 addtag 方式的独特。而在吉司机线段树中,由于要维护很多信息,所以每个信息 pushuppushdown 的方式会有点不一样,这是一点。

第二个就是很重要的一点,线段树的分治思想。我们想想在最朴素的线段树中,当我们发现当前处理的区间 \([l,r]\) 不完全包含于更新或查询的区间 \([L,R]\) 的时候,我们就会把这个问题向左儿子和右儿子分治。这是最朴素的限制:区间范围的限制。

当然,在很多题中,一个区间范围的限制是远远不够的,我们甚至可能受到我们所维护的信息的限制。比如在吉司机线段树中,如果我们要对区间取 \(\min\) 结果发现要取 \(\min\) 的值小于区间次大值,我们肯定是无法待在当前结点就把区间问题处理了。那怎么办呢?

记住一个定律:当你推了很久的公式,发现无论如何加 \(\text{tag}\) 都无法维护当前结点的信息的时候,直接往左右儿子递归。当我们已经记录了足够多的信息,并且不能仅在当前结点就处理区间问题的时候,就相当于当前结点的条件不够,要往左右儿子递归。再不济,递归到底层结点也是可以解决问题的,而往往我们不用递归到底层。

吉司机线段树就是这样分治思想的一个典型范例,而李超线段树也是一样的。一个区间中要更新的一条线段加到这个区间的时候,原来这个区间里有一堆线段,除非这条线段在所有之前的线段之上,你并不能知道哪些该被更新哪些不该被更新,这个时候就要递归到左右子树中加 \(\text{tag}\)。这也就是李超线段树时间复杂度 \(O(n \log^2 n)\) 的原因:线段树本身是 \(O(n \log n)\) 的,但是加 \(\text{tag}\) 是运用了线段树的分治思想,所以多了一个 \(\log\)

posted @ 2025-01-15 21:20  KarmaticEnding  阅读(4)  评论(0)    收藏  举报