博客
关于我
AcWing 798. 差分矩阵
阅读量:353 次
发布时间:2019-03-04

本文共 2719 字,大约阅读时间需要 9 分钟。

为了高效处理大规模矩阵的多个区间加法操作,我们采用差分数组(Difference Array)方法。这种方法将每个操作分解为四个点的增减,避免了直接遍历矩阵的高时间复杂度。

方法思路

  • 差分数组初始化:创建一个差分数组 diff,其大小为 (m+2) x (n+2),以防止越界。
  • 处理每个操作:对于每个操作 (x1, y1, x2, y2, c),在 diff 数组中进行以下更新:
    • diff[x1][y1] += c
    • diff[x1][y2+1] -= c
    • diff[x2+1][y1] -= c
    • diff[x2+1][y2+1] += c
  • 计算前缀和:首先计算 diff 的行前缀和,然后计算列前缀和,得到每个位置的增量。
  • 更新原始矩阵:将计算得到的增量加到原始矩阵上,得到最终结果。
  • 解决代码

    import java.io.*;class Main {    public static void main(String[] args) throws Exception {        BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));        String[] strNums = buf.readLine().split(" ");        int m = Integer.valueOf(strNums[0]);        int n = Integer.valueOf(strNums[1]);        int q = Integer.valueOf(strNums[2]);        int[][] a = new int[m + 2][n + 2];        int[][] diff = new int[m + 2][n + 2];        for (int i = 1; i <= m; ++i) {            String[] nums = buf.readLine().split(" ");            for (int j = 1; j <= n; ++j) {                int k = Integer.valueOf(nums[j - 1]);                diff[i][j] += k;            }        }        for (int i = 0; i < q; ++i) {            String[] nums = buf.readLine().split(" ");            int x1 = Integer.valueOf(nums[0]);            int y1 = Integer.valueOf(nums[1]);            int x2 = Integer.valueOf(nums[2]);            int y2 = Integer.valueOf(nums[3]);            int k = Integer.valueOf(nums[4]);            diff[x1][y1] += k;            if (y2 + 1 <= m) {                diff[x1][y2 + 1] -= k;            }            if (x2 + 1 <= n) {                diff[x2 + 1][y1] -= k;                if (y2 + 1 <= m) {                    diff[x2 + 1][y2 + 1] += k;                }            }        }        for (int i = 1; i <= m; ++i) {            for (int j = 1; j <= n; ++j) {                if (i > 1) {                    diff[i][j] += diff[i - 1][j];                }                if (j > 1) {                    diff[i][j] += diff[i][j - 1];                    if (i > 1) {                        diff[i][j] -= diff[i - 1][j - 1];                    }                }            }        }        for (int i = 1; i <= m; ++i) {            for (int j = 1; j <= n; ++j) {                a[i][j] += diff[i][j];            }        }        for (int i = 1; i <= m; ++i) {            writer.write(String.join(" ", String.valueOf(a[i][j]) + "\n"));        }        buf.close();        writer.flush();        writer.close();    }}

    代码解释

  • 读取输入:首先读取矩阵的尺寸 nm,以及操作的数量 q
  • 初始化矩阵和差分数组:创建原始矩阵 a 和差分数组 diff
  • 读取矩阵数据:将初始矩阵数据读入,并更新差分数组。
  • 处理每个操作:读取每个操作,更新差分数组。
  • 计算前缀和:先计算行前缀和,再计算列前缀和,得到增量矩阵。
  • 更新矩阵:将增量加到原始矩阵上,生成最终结果。
  • 输出结果:将最终矩阵按行输出。
  • 这种方法通过差分数组将多个区间加法操作高效处理,避免了直接遍历矩阵的高时间复杂度,确保了程序在大规模数据下的性能。

    转载地址:http://pkre.baihongyu.com/

    你可能感兴趣的文章