为了不超界 有两种情况:
下标从0 0开始 那么前缀和数组si j 表示i j之前的所有数之和
下标从1 1开始 那么前缀和数组si j 表示包括i j及其以前所有数之和
相当于每个点的二维前缀和都是当前位置向右下移一个后表示
就是在从1开始的基础上 前缀和公式基本不变(最后加上的数不同) 求前缀和时下标整体+1
#include <iostream>
using namespace std;
const int N = 1010;
int a[N][N], s[N][N];
int main() {
int n, m, q;
cin >> n >> m >> q;
<!--下标从0开始-->
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++) {
scanf("%d", &a[i][j]);
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
scanf("%d", &a[i][j]);
s[i][j] = s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1] + a[i - 1][j - 1]; // 求前缀和
}
while (q--) {
int x1,y1,x2,y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
// 算子矩阵的和
printf("%d\n", s[x2+1][y2+1] - s[x2+1][y1] - s[x1][y2+1] + s[x1][y1]);
}
<!--下标从1开始-->
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
scanf("%d", &a[i][j]);
s[i][j] = s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1] + a[i][j]; // 求前缀和
}
while (q--) {
int x1,y1,x2,y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
// 算子矩阵的和
printf("%d\n", s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1]);
}
return 0;
}