这可能是我最后一次更新博客了呢
# 前言
很久之前,我初学树状数组的时候感觉非常的复杂、神奇、晦涩难懂。。。
果然还是我太菜了。后来了解到线段树的可删减性,这两者就自然而然的联系在一起了。
# 线段树的可删减性
很显然,对于一些区间操作的问题,线段树有着绝对的优势,基本上只要是区间查询之类的问题,那线段树是没跑了。
但是如果我们要查询的是前缀和这样的东西的话,会不会感觉线段树中的一些东西是多余的呢?
这么说可能有些不好理解,画画图就好:
上图如果看不清楚,请在新标签页中打开。(蓝色为节点标号,红色是区间端点)
假设我们查询到位置 9 的前缀和,那么答案就等于 2 号节点和 6 号节点的和。
这两个节点有什么奇怪的性质?
显然它们都是左孩子啊,那是不是所有的前缀和都是仅由左孩子节点构成的呢。
再试一下,就会发现,都是这样的。如何证明?
从根节点开始,答案有以下两种情况。
- 在左孩子中。
- 整个左孩子就是答案。
- 整个左孩子加上右孩子的一部分。
先看第二种情况。。。那这根本没有悬念吧,只有左孩子。
那再看第一种情况,在左孩子中查找答案。那么答案还是分成上面的三种情况。
关键的就是来看第三种情况,那在右孩子中的答案就变成了 mid 到查询区间的右端点的和。
如果把左子树看做一个整体的话,只有变成了上面的差前缀和的问题。也就是说如果在右孩子中存在一部分答案的话,就会已知按照上面的三种情况划分下去,直到出现了第二种情况。
那第一种情况也是如此,已知分下去,问题要么直接变成第二种情况,要么先变成第三种情况再变成第二种情况。
而且观察我们的路径,会发现对答案有贡献的节点全部都是左端点。也就是说又断电时可以省略掉的。
如下图。
这就是线段树的可删减性。
# 再说树状数组
树状数组能解决的不正是前缀和的查询吗?那么我们再来看上面的图,删掉右孩子后,是不是变成了一个树状数组呢?
这就是两者之间的关系。
原文地址:https://www.cnblogs.com/bljfy/p/9926194.html