超级树状数组
众所周知:
- 线段树的代码长,常数大;
- 树状数组的代码短,常数小,甚至可以通过 106 量级的数据。
所以,能不能实现一个可以区间修改、区间查询的树状数组呢?
由于涉及区间操作,考虑差分数组 {dn}。
区间修改
对于原数组 [l, r] 区间每个数加 w。
可以转化为两次单点修改,即 l 单点处加 +w,r + 1 单点处加 −w。
区间查询
对于原数组 [l, r] 区间求和。
显然
观察每一个
所以 d1 的贡献为 u,d2 的贡献为 u − 1,d3 的贡献为 u − 2,……,du 的贡献为 1。
故可得 dk 的贡献为 u − j + 1。
发现 u + 1 的值是固定的,可以提取出来:
因此同时使用两个树状数组维护 {dn}、{n × dn} 即可,该技巧即为超级树状数组。
代码实现
1 | typedef long long lint; |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 一个Oier!
