题意整理。
- 给定一个n行m列的矩阵。
- 有q次查询,每次查询给定子矩阵的左上角坐标和右下角坐标,输出子矩阵中所有元素的累加和。
方法一(二维前缀和)
1.解题思路
- 首先对矩阵进行预处理,得到对应的前缀和矩阵。
- 利用前缀和矩阵相应区域的加减运算,即可得到对应子矩阵中所有元素的累加和。
图解展示(图中presum[3][4]除了包括绿色部分,还包括其它重叠的部分,其它几项也一样,另外presum[1][1]被多减了一次,所以最后要加一次):
2.代码实现
import java.util.*;
public class Main {
public static void main(String[] args){
//标准输入
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int q = sc.nextInt();
//定义并初始化矩阵
int[][] arr=new int[n][m];
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
arr[i][j]=sc.nextInt();
}
}
//定义并初始化二维前缀和
long[][] presum=new long[n+1][m+1];
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
presum[i+1][j+1]=presum[i+1][j]+presum[i][j+1]-presum[i][j]+arr[i][j];
}
}
//q次查询
while(q-->0){
//查询子矩阵的左上角和右下角坐标
int x1=sc.nextInt();
int y1=sc.nextInt();
int x2=sc.nextInt();
int y2=sc.nextInt();
System.out.println(presum[x2][y2]-presum[x2][y1-1]-presum[x1-1][y2]+presum[x1-1][y1-1]);
}
}
}
3.复杂度分析
- 时间复杂度:需要遍历数组中所有元素构建前缀和数组,预处理的时间复杂度为,每次查询只需进行一次运算,所以查询的时间复杂度为。
- 空间复杂度:需要额外长度为的前缀和矩阵,所以空间复杂度为。