1、算法思路
1.一维前缀和
对于一个包含元素 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1,a2,...,an的数组a,设 S i = a 1 + a 2 + . . . + a i S_i = a_1 + a_2 + ... + a_i Si=a1+a2+...+ai,那么 S i S_i Si就是 [ a 1 , a 2 , . . . , a i ] [a_1,a_2,...,a_i] [a1,a2,...,ai]的前缀和。
- 如何求前缀和
S i = a 1 + a 2 + . . . + a i = S i − 1 + a i S_i = a_1 + a_2 + ... + a_i = S_{i-1} + a_i Si=a1+a2+...+ai=Si−1+ai - 前缀和的作用
记录下前缀和,可以在 O ( 1 ) O(1) O(1)的时间内,计算出一个区间的元素之和。
例如我们想要求出 a l + a l + 1 + . . . + a r a_l + a_{l+1} + ... + a_r al+al+1+...+ar,可以利用前缀和
S r − S l − 1 = a 1 + a 2 + . . . + a l − 1 + a l + . . . + a r − a 1 + a 2 + . . . + a l − 1 = a l + a l + 1 + . . . + a r S_r - S_{l - 1} = a_1 + a_2 + ...+a_{l -1} + a_{l} + ... + a_r - a_1 + a_2 + ... + a_{l -1} = a_l + a_{l+1} + ... + a_r Sr−Sl−1=a1+a2+...+al−1+al+...+ar−a1+a2+...+al−1=al+al+1+...+ar,这样就求得了这个区间和
2.二维前缀和
(下面i表示行,j表示列)
和一维前缀和类似, 对于一个包含元素
a
i
,
j
a_{i,j}
ai,j的二维数组a,设
S
i
,
j
=
a
0
,
0
+
a
0
,
1
+
.
.
.
+
a
i
,
j
S_{i,j} = a_{0,0} + a_{0,1} + ... + a_{i,j}
Si,j=a0,0+a0,1+...+ai,j,那么
S
i
,
j
S_{i,j}
Si,j就是这些元素的前缀和。用图片解释如下图
对于这个标红的位置,其前缀和为(1 + 2 + 3 + 5 + 6 + 7)= 24
- 如何求前缀和
先说结论,结论之后我们找一个例子看看
S i , j = S i , j − 1 + S i − 1 , j − S i − 1 , j − 1 + a i , j S_{i,j} = S_{i,j -1} + S_{i - 1,j} -S_{i-1,j-1} + a_{i,j} Si,j=Si,j−1+Si−1,j−Si−1,j−1+ai,j
对于标红的位置(1,2)来说,上式中 S i , j − 1 S_{i,j-1} Si,j−1( S 1 , 1 S_{1,1} S1,1)即为标蓝的方格
S i − 1 , j ( S_{i-1,j}( Si−1,j(S_{0,2} ) ) )即为下面的蓝色方格区域
二者之和即为
这里深颜色的地方代表的是上面两块的重合地带,加重了,所以要减去 S i − 1 , j − 1 S_{i-1,j-1} Si−1,j−1( S 0 , 1 S_{0,1} S0,1)
减完之后再加上 a i , j a_{i,j} ai,j本身,就求出了前缀和。 - 前缀和的作用
其实作用跟一维类似,就是用来快速求出某个区域内的和
2、模板代码
基本不需要什么模板,理解了含义就能写出
一维情况
S[i] = a[1] + a[2] + ... a[i]
a[l] + ... + a[r] = S[r] - S[l - 1]
二维情况
S[i, j] = 第i行j列格子左上部分所有元素的和,按照上面的分析去求即可
以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵的和为:
S[x2, y2] - S[x1 - 1, y2] - S[x2, y1 - 1] + S[x1 - 1, y1 - 1]