一般的树状数组对于可减信息可以实现单点修改+区间查询,如果套用差分,可以实现区间修改+单点查询。
设要维护的序列\(a\),差分数组\(d_i = a_i - a_{i-1}\)
要求\([1, x]\)区间的和:
\[\begin{aligned}
query(x) &=
\Sigma_{i=1}^x a_i \\&= \Sigma_{i=1}^x \Sigma_{j=1}^i d_i \ &= \Sigma_{i=1}^x (x-i+1)d_i
\end{aligned}
\]
维护一个序列\(ds_i = (i-1)d_i\)
则和为\(n \Sigma_{i=1}^x d_i - \Sigma_{i=1}^xds_i\)
#define lb(x) (x & (-x))
int d[N], ds[N];
int ask_a(int *a, int x){int ans = 0;for(;x ; x-=lb(x)) ans += a[x]; return ans;}
void upd_a(int *a, int x, int v){for(; x<=n; x+=lb(x)) a[x] += v;}
int ask(int x){return ((ll)ask_a(d, x) * x - ask_a(ds, x);}
void upd(int x, int v){upd_a(d, x, v); upd_a(ds, x, (ll)v * (x - 1));}
打一些题很方便,比线段树友好多了,常数也小
原文:https://www.cnblogs.com/RiverHamster/p/BIT-seq-operation.html