一维前缀和可以理解为数组的前 $n$ 项和,通过预处理出前缀和数组,使某段区间的和的查询变为 $O(1)$,是一种重要的优化手段。
前缀和数组的建立方法如下:
#define N 1000
int a[N], prefix[N];
int main() {
int n; cin >> n;
for (int i = 1; i <= n; i++) { // 人为从下标 1 开始,处理边界条件 a[0] = 0
cin >> a[i];
prefix[i] = prefix[i - 1] + a[i];
}
}
对于数组 $a[1\dots n]$,区间 $[l,r]$ 的和就是 $\text{prefix}[r]-\text{prefix}[l-1]$.
二维前缀和定义为从数组左上角到给定的点 $(i,j)$ 包围的矩形内元素的和。
设数组 $a[1\dots n]$,则根据递推可以得到 $\text{prefix}[i][j]=\text{prefix}[i][j-1]+\text{prefix}[i-1][j]-\text{prefix}[i-1][j-1]+a[i][j]$,如图:

故可以得到代码:
#define N 1000
#define M 600
int a[N][M], prefix[N][M];
int main() {
int n, m; cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
prefix[i][j] = prefix[i - 1][j] + prefix[i][j - 1] - prefix[i - 1][j - 1] + a[i][j];
}
}
}
则从 $(r_1,c_1)$ 到 $(r_2, c_2)$ 的和为
$$ \text{prefix}[r_2][c_2]-\text{prefix}[r_1-1][c_2]-\text{prefix}[r_2][c_1-1]+\text{prefix}[r_1-1][c_1-1] $$