一、思路
和一维差分的思想差不多,但是二维处理却麻烦很多(这题用的是BufferedReader和BufferedWriter,因为用Scanner超时了,真的对Java太不友好了,难受)。s[i] [j]为差分数组,我们这里把原数组也当作只处理当前位置的差分来处理,这样可以方便统一操作。insert函数就是用来处理差分的。最后再还原数组就行了。
二、代码模板
import java.io.*;
public class Main {
static int[][] s;
public static void insert(int x1, int y1, int x2, int y2, int num){
s[x1][y1] += num;
s[x2 + 1][y1] -= num;
s[x1][y2 + 1] -= num;
s[x2 + 1][y2 + 1] += num;
}
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
String[] str = in.readLine().split(" ");
int n = Integer.parseInt(str[0]);
int m = Integer.parseInt(str[1]);
int q = Integer.parseInt(str[2]);
s = new int[n + 2][m + 2]; //差分数组
for (int i = 1; i <= n; i ++){
str = in.readLine().split(" "); //读入原数组
for (int j = 1; j <= m; j++)
insert(i, j, i, j, Integer.parseInt(str[j - 1])); //因为str下标为0开始
}
for (int i = 0; i < q; i++){
str = in.readLine().split(" ");
int x1 = Integer.parseInt(str[0]);
int y1 = Integer.parseInt(str[1]);
int x2 = Integer.parseInt(str[2]);
int y2 = Integer.parseInt(str[3]);
int num = Integer.parseInt(str[4]);
insert(x1, y1, x2, y2, num); //操作差分数组
}
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m;j++){ //还原数组
s[i][j] = s[i][j] + s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];
out.write(s[i][j] + " ");
}
out.write("\n");
}
out.flush(); //刷新
}
}
三、复杂度分析
- 时间复杂度:O(m * n)
- 空间复杂度:O(m * n)