树状数组
题目 树状数组模板1 题目大意:给定一个序列,要求支持两种操作:1.将某个数加上 \(x\) ,2.查询区间某部分的和。 题目 树状数组模板2 题目大意:给定一个序列,要求支持两种操作:1.将区间内的每个数加上 \(x\) ,2.查询某个数。 分析 由于第一题与第二题实际上是等价的(稍后会说明),我们以下仅讨论第一题。我们先以最简单的数组来考虑,显然操作1是 \(O(1)\) ,操作2是 \(O(n)\) 的,总体复杂度 \(O(nm)\) ,很明显会超时。这时我们就会想到用前缀和来优化操作2,这样的话操作2是 \(O(1)\) 的,但是操作1是 \(O(n)\) 的,总体复杂度仍为 \(O(nm)\) ,会超时。有没有一种数据结构,可以使操作1和操作2都是 \(O(1)\) 的呢?仅目前来看是不存在的。于是我们退而求其次寻找一种数据结构,使操作1和操作2都是 \(O(\log n)\) 的。 树状数组(又称二叉索引树,Fenwick树)是一类最基础的树形数据结构。它支持 \(O(\log n)\) 进行区间修改单点查询或区间查询单点修改,亦即上述两道题的操作。具体来说,树状数组自身本质上仍是一个数组。我们令 \(a\) 为原数组, \(c\) 为树状数组,假定 \(i\) 二进制最后有 \(j\) 个0,则有 \(c_i=\sum_{k=0}^{2^j}a_{i-k}\) 。