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

本文共 2780 字,大约阅读时间需要 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/

    你可能感兴趣的文章
    No new migrations found. Your system is up-to-date.
    查看>>
    No qualifying bean of type XXX found for dependency XXX.
    查看>>
    No resource identifier found for attribute 'srcCompat' in package的解决办法
    查看>>
    no session found for current thread
    查看>>
    No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android
    查看>>
    NO.23 ZenTaoPHP目录结构
    查看>>
    no1
    查看>>
    NO32 网络层次及OSI7层模型--TCP三次握手四次断开--子网划分
    查看>>
    NoClassDefFoundError: org/springframework/boot/context/properties/ConfigurationBeanFactoryMetadata
    查看>>
    Node JS: < 一> 初识Node JS
    查看>>
    Node Sass does not yet support your current environment: Windows 64-bit with Unsupported runtime(72)
    查看>>
    Node-RED中使用JSON数据建立web网站
    查看>>
    Node-RED中使用json节点解析JSON数据
    查看>>
    Node-RED中使用node-random节点来实现随机数在折线图中显示
    查看>>
    Node-RED中使用node-red-browser-utils节点实现选择Windows操作系统中的文件并实现图片预览
    查看>>
    Node-RED中使用node-red-contrib-image-output节点实现图片预览
    查看>>
    Node-RED中使用node-red-node-ui-iframe节点实现内嵌iframe访问其他网站的效果
    查看>>
    Node-RED中使用Notification元件显示警告讯息框(温度过高提示)
    查看>>
    Node-RED中实现HTML表单提交和获取提交的内容
    查看>>
    Node-RED中建立Websocket客户端连接
    查看>>