二维差分

2021-10-24 常用算法 差分

# 一、算法思想

相比于 一维差分,二维差分考虑的是差分矩阵的前缀和为原矩阵。

同样的,考虑对 AA 矩阵中,左上角坐标 (x1,y1)(x_1,y_1)、右下角坐标 (x2,y2)(x_2,y_2) 的子矩阵内的元素加上 cc。那么可以通过对差分矩阵 BBO(1)O(1) 的时间内完成,如下:

b[x1][y1] += c;
b[x2 + 1][y1] -= c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y2 + 1] += c;
1
2
3
4

# 二、算法模板

Go

type Difference2D struct {
    diff [][]int
    n, m int
}

// NewDifference2D 初始化二维差分数组
func NewDifference2D(n, m int) *Difference2D {
    diff := make([][]int, n+2)
    for i := range diff {
        diff[i] = make([]int, m+2)
    }
    return &Difference2D{
        diff: diff,
        n:    n,
        m:    m,
    }
}

// 给子矩阵内的元素加上 c
// 子矩阵的左上角和右下角坐标为 (x1, y1) 和 (x2, y2)
func (df *Difference2D) insert(x1, y1, x2, y2, c int) {
    df.diff[x1][y1] += c
    df.diff[x2+1][y1] -= c
    df.diff[x1][y2+1] -= c
    df.diff[x2+1][y2+1] += c
}

// 获取最终矩阵
func (df *Difference2D) final() (ans [][]int) {
    ans = make([][]int, df.n+1)
    for i := range ans {
        ans[i] = make([]int, df.m+1)
        for j := range ans[i] {
            ans[i][j] = df.diff[i][j]
        }
    }
    for i := 1; i <= df.n; i++ {
        for j := 1; j <= df.m; j++ {
            ans[i][j] += ans[i-1][j] + ans[i][j-1] - ans[i-1][j-1]
        }
    }
    for i := range ans {
        ans[i] = ans[i][1:]
    }
    ans = ans[1:]
    return
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

# 三、代码实战

# AcWing 0798


题目:差分矩阵

输入一个 nnmm 列的整数矩阵,再输入 qq 个操作,每个操作包含五个整数 x1,y1,x2,y2,cx_1,y_1,x_2,y_2,c,其中 (x1,y1)(x1,y1)(x2,y2)(x2,y2) 表示一个子矩阵的左上角坐标和右下角坐标。

每个操作都要将选中的子矩阵中的每个元素的值加上 cc

请你将进行完所有操作后的矩阵输出。

输入格式

第一行包含三个整数 nnmmqq

接下来 nn 行,每行包含 mm 个整数,表示整数矩阵。

接下来 qq 行,每行包含五个整数 x1,y1,x2,y2,cx_1,y_1,x_2,y_2,c,表示一个操作。

输出格式

nn 行,每行 mm 个整数,表示所有操作进行完毕后的最终矩阵。

数据范围

1n,m10001 \le n,m \le 1000
1q2×1051 \le q \le 2 \times 10^5
1x1x2n1 \le x_1 \le x_2 \le n
1y1y2m1 \le y_1 \le y_2 \le m
1000c1000-1000 \le c \le 1000
1000矩阵内元素的值1000-1000 \le \text{矩阵内元素的值} \le 1000

输入样例:

3 4 3

1 2 2 1

3 2 2 1

1 1 1 1

1 1 2 2 1

1 3 2 3 2

3 1 3 4 1

输出样例:

2 3 4 1

4 3 4 1

2 2 2 2

解答代码:

    Last Updated: 2023-01-28 4:31:25