博客
关于我
AcWing 798. 差分矩阵
阅读量:354 次
发布时间: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/

    你可能感兴趣的文章
    POSIX thread编程中关于临界区内条件变量的分析
    查看>>
    POSIX与程序可移植性
    查看>>
    posix多线程有感--自旋锁
    查看>>
    SpringBoot中集成海康威视SDK实现布防报警数据上传/交通违章图片上传并在linux上部署(附示例代码资源)
    查看>>
    POSIX标准和XSI扩展
    查看>>
    post install error,please remove node_moules before retry
    查看>>
    PostGIS中获取所有EPSG的编码以及对应Proj4字符串
    查看>>
    PostGIS在Windows上的下载与安装
    查看>>
    postgis数据库优化_postgresql 性能优化
    查看>>
    Postgres Docker版本安装mysql_fdw 插件
    查看>>
    Postgres invalid command \N数据恢复处理
    查看>>
    Postgres like 模糊查询匹配集合
    查看>>
    Postgres 自定义函数内实现 in 操作符的递归查询
    查看>>
    Postgres 返回当前时间前后指定天数的集合
    查看>>
    postgres--vacuum
    查看>>
    postgres--wal
    查看>>
    postgres--流复制
    查看>>
    postgres10配置huge_pages
    查看>>
    PostgreSQL 10.0 preview 变化 - pg_xlog,pg_clog,pg_log目录更名为pg_wal,pg_xact,log
    查看>>
    PostgreSQL 10.1 手册_部分 II. SQL 语言_第 15章 并行查询_15.2. 何时会用到并行查询?...
    查看>>