对于一个数列 (A) ,我们这样定义它的前缀和数列 (B) :
[B_i = sumlimits^{i}_{j = 1}A_j
]
我们可以简单地理解为前缀和数列的第 (n) 项就是原数列前 (n) 项的和。
For Example :
(A: 1 2 4 1 6 7\ B: 1 3 7 8 14 21)
对于数列 (A) 求一个区间 ([l,r]) 的和,可以通过其前缀和数列 (B) 来 (O(1)) 得到结果,其结果表示为前缀和相减的形式:
[ ext{sum}(l,r)=sumlimits^{r}_{i = l}A_i=B_r - B_{l-1}
]
我们可以类似地求出树上的前缀和:我们设 (all_{i}) 为节点 (i) 到根节点的权值之和,( ext{LCA}(x,y)) 为 (x) 和 (y) 的最近公共祖先。分个类:
- 点权:(xsim y) 的权值和为: (all_x + all_y - all_{ ext{LCA}(x,y)} - all_{fa_{ ext{LCA}(x,y)}})
- 边权:(xsim y) 的权值和为: (all_x + all_y - 2 all_{ ext{LCA}(x,y)})
对于一个数列 (A) ,我们这样定义它的差分数列 (B) :
[B_1 = A_1, B_i=A_i-A_{i-1}(2le ile n)
]
差分可以当做是前缀和的逆运算。
For Example :
(
A:9quad 3 5quad 4quad 2\
B:9 -6 2 -1 -2
)
这个东西支持区间修改,以及在所有修改完之后再查询。
使数列 (A) 中的区间 ([l,r]) 都加上 (d) 的话,我们只需要 (B_l leftarrow B_l + k, B_{r + 1} leftarrow B_{r + 1} - k) 就可以了。