树状数组及其简单扩展
树状数组及其简单扩展 不对树状数组做详细讲解,只对应用类型做总结. 一维树状数组 单点修改,区间查询 由于树状数组维护的是前缀信息,所以区间查询直接利用前缀特性相减即可. 单点修改只需从开始位置向后更新即可. 区间修改,单点查询 树状数组只支持单点修改,那么如何处理区间修改呢? 考虑常见的区间修改转单点修改的套路:差分. 而差分数组的前 \(n\) 项和也恰好就是真正的 \(v_i\) . 所有直接差分去做即可. 区间修改,区间查询 同理,先差分,差分后区间修改是没有区别的. 而这里我们发现,我们只能得到对应的单点值,却不能直接得到对应的区间和. 难道要套一种可以区间求和的数据结构嘛?答案是否定的. 我们发现,我们要求的其实是这个: \[\sum_{i=l}^r{\sum_{j=1}^i}{d_j}\] 其中, \(d_j\) 就是差分数组.对于内层求和显然可以直接在树状数组中查询得到. 那么怎么处理外层呢?再 \(for\) 一遍是显然不可能的. 所以我们重新考虑: 令 \(sum_i\) 表示前缀和. \[\begin{array}{c}{\operatorname{sum}[i]=\sum_{j=1}^{i} v[j]+\sum_{j=1}^{i} \operatorname{d}[j] *(i-j+1)} \\ {\operatorname{sum}[i]=\sum_{j