树状数组之区间修改,区间查询
原理
我们先开俩数组;
- 原数组:a [i], 每一个元素的值
- 差分数组:b [i], 下标 i 的元素存放 a[i]-a[i-1] 的差值,b[1]=a[1]
我们可以得到下面的公式:
于是,我们得到了一个 重要公式
我们设:
- b1 [i] 数组表示:b1 [i] = a [i]-a [i-1], 差分数组
- b2 [i] 数组表示:b2 [i] = i* b1 [i]
- c1 [i] 针对 b1 的树状数组
- c2 [i] 针对 b2 的树状数组
代码
int n, m,mod;
int c[N],ic[N];; // 建立在b[i]与i*b[i]上的bit
inline int lowbit(int x) { return x & -x; }
inline int fa(int p) { return p + lowbit(p); }
inline int left(int p) { return p - lowbit(p); }
void change(int p, int v) {
for (; p <= N; p = fa(p))
c[p] += v;
}
inline void change_range(int l, int r, int v) {
change(l, v);
change(r + 1, -v);
}
int query_c(int p, int c[]) {
int sum = 0;
for (; p > 0; p = left(p)) sum += c[p];
return sum;
}
int query(int p) { //前缀合
return (p + 1) * query_c(p, c) - query_c(p, ic);
}