首先从前缀和出发,在前缀和中,我们构造前缀和数组的方式是:
这样的构造方式使得,我们的构造过程是O(n)的,查找过程是O(1)的,整体的时间复杂度是O(n)。
树状数组通过改变求和数组的构造方式,使得构造和查询的过程都是O(logn)的。
我们从二进制的角度来考虑。
对于长度为n的原数组a,它的求和数组s中位于第x位的数的值是:
我们每次只需要对这部分求和就好了,时间复杂度就会是log级别的。
接下来,我们试图找到一些规律,方便我们对这些部分进行求和。
画出c数组的组成:
可以得出前缀和的求和公式:
当我们修改某个a值时,要怎么维护对应的c值呢?
在图中可以发现,每个节点只有一个唯一的父亲,并且这个父亲的序号是,把比当前节点最高位的更高一位改为1。
因此,我们的修改操作就是:
最后要补充一点:树状数组求的是1-x的总和,而不是0-x