子矩阵的和
题目描述
题干
输入一个 n 行 m 列的整数矩阵,再输入 q 个询问,每个询问包含四个整数 x1 , y1 , x2 , y2,表示一个子矩阵的左上角坐标和右下角坐标。
对于每个询问输出子矩阵中所有数的和。
数据范围
1 ≤ n , m ≤ 1000 , 1 ≤ q ≤ 200000 , 1≤n,m≤1000,1≤q≤200000, 1≤n,m≤1000,1≤q≤200000,
1 ≤ x 1 ≤ x 2 ≤ n , 1 ≤ y 1 ≤ y 2 ≤ m , − 1000 ≤ 矩阵内元素的值 ≤ 1000 1≤x1≤x2 ≤n,1≤y1≤y2≤m,-1000≤矩阵内元素的值≤1000 1≤x1≤x2≤n,1≤y1≤y2≤m,−1000≤矩阵内元素的值≤1000
输入描述
第一行包含三个整数 n,m,q。
接下来 n 行,每行包含 m 个整数,表示整数矩阵。
接下来 q 行,每行包含四个整数 x1,y1,x2,y2,表示一组询问。
输出描述
共 q 行,每行输出一个询问的结果。
样例
输入
3 4 3
1 7 2 4
3 6 2 8
2 1 2 3
1 1 2 2
2 1 3 4
1 3 3 4
输出
17
27
21
思路
首先读完题即可知这是一道二维前缀和的题目
所以我们就自然可以先处理上前缀和数组
再用前缀和数组中的
[
x
2
]
[
y
2
]
−
[
x
2
]
[
y
1
−
1
]
−
[
x
1
−
1
]
[
y
2
]
+
[
x
1
−
1
]
[
y
1
−
1
]
[x2][y2]-[x2][y1-1]-[x1-1][y2]+[x1-1][y1-1]
[x2][y2]−[x2][y1−1]−[x1−1][y2]+[x1−1][y1−1]即可
AC代码
#include<iostream>
#include<cstdio>
using namespace std;
long long sum[1005][1005];
int a[1005][1005];
int main() {
int n, m, q;
int x1, x2, y1, y2;
//输入
scanf("%d%d%d", &n, &m, &q);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
scanf("%d", &a[i][j]);
}
}
//处理前缀和
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
sum[i][j] = sum[i - 1][j] + sum[i][j - 1] + a[i][j] - sum[i - 1][j - 1];
}
}
//通过预处理的前缀和得出结果并输出
for (int i = 0; i < q; i++) {
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
int ans;
ans = sum[x2][y2] - sum[x2][y1 - 1] - sum[x1 - 1][y2] + sum[x1 - 1][y1 - 1];
printf("%d\n", ans);
}
return 0;
}