从线段树的可删减性谈树状数组

Posted bljfy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从线段树的可删减性谈树状数组相关的知识,希望对你有一定的参考价值。

这可能是我最后一次更新博客了呢

# 前言

很久之前,我初学树状数组的时候感觉非常的复杂、神奇、晦涩难懂。。。

果然还是我太菜了。后来了解到线段树的可删减性,这两者就自然而然的联系在一起了。

 

# 线段树的可删减性

很显然,对于一些区间操作的问题,线段树有着绝对的优势,基本上只要是区间查询之类的问题,那线段树是没跑了。

但是如果我们要查询的是前缀和这样的东西的话,会不会感觉线段树中的一些东西是多余的呢?

这么说可能有些不好理解,画画图就好:

技术分享图片

上图如果看不清楚,请在新标签页中打开。(蓝色为节点标号,红色是区间端点)

假设我们查询到位置 9 的前缀和,那么答案就等于 2 号节点和 6 号节点的和。

这两个节点有什么奇怪的性质?

显然它们都是左孩子啊,那是不是所有的前缀和都是仅由左孩子节点构成的呢。

再试一下,就会发现,都是这样的。如何证明?

从根节点开始,答案有以下两种情况。

  • 在左孩子中。
  • 整个左孩子就是答案。
  • 整个左孩子加上右孩子的一部分。

先看第二种情况。。。那这根本没有悬念吧,只有左孩子。

那再看第一种情况,在左孩子中查找答案。那么答案还是分成上面的三种情况。

关键的就是来看第三种情况,那在右孩子中的答案就变成了 mid 到查询区间的右端点的和。

如果把左子树看做一个整体的话,只有变成了上面的差前缀和的问题。也就是说如果在右孩子中存在一部分答案的话,就会已知按照上面的三种情况划分下去,直到出现了第二种情况。

那第一种情况也是如此,已知分下去,问题要么直接变成第二种情况,要么先变成第三种情况再变成第二种情况。

而且观察我们的路径,会发现对答案有贡献的节点全部都是左端点。也就是说又断电时可以省略掉的。

如下图。

技术分享图片

这就是线段树的可删减性。

 

# 再说树状数组

树状数组能解决的不正是前缀和的查询吗?那么我们再来看上面的图,删掉右孩子后,是不是变成了一个树状数组呢?

这就是两者之间的关系。

 

以上是关于从线段树的可删减性谈树状数组的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode-线段树和树状数组

吊打线段树的超级树状数组

树状数组的树状数组的经典操作

树状数组和线段树有啥区别?

树状数组

树状数组(Binary Indexed Tree)