基础算法-差分矩阵

news2024/9/23 21:30:18

(一)课堂笔记

(二)思路详解

如果扩展到二维,我们需要让二维数组被选中的子矩阵中的每个元素的值加上c,是否也可以达到O(1)的时间复杂度。答案是可以的,考虑二维差分。

a[][]数组是b[][]数组的前缀和数组,那么b[][]是a[][]的差分数组

原数组: a[i][j]

我们去构造差分数组: b[i][j]

使得a数组中a[i][j]是b数组左上角(1,1)到右下角(i,j)所包围矩形元素的和。

如何构造b数组呢?

我们去逆向思考。

同一维差分,我们构造二维差分数组目的是为了 让原二维数组a中所选中子矩阵中的每一个元素加上c的操作,可以由O(n*n)的时间复杂度优化成O(1)

已知原数组a中被选中的子矩阵为 以(x1,y1)为左上角,以(x2,y2)为右下角所围成的矩形区域;

始终要记得,a数组是b数组的前缀和数组,比如对b数组的b[i][j]的修改,会影响到a数组中从a[i][j]及往后的每一个数。

假定我们已经构造好了b数组,类比一维差分,我们执行以下操作
来使被选中的子矩阵中的每个元素的值加上c

b[x1][y1] += c;

b[x1,][y2+1] -= c;

b[x2+1][y1] -= c;

b[x2+1][y2+1] += c;

每次对b数组执行以上操作,等价于:

for(int i=x1;i<=x2;i++)
  for(int j=y1;j<=y2;j++)
    a[i][j]+=c;

b[x1][ y1 ] +=c ; 对应图1 ,让整个a数组中蓝色矩形面积的元素都加上了c。
b[x1,][y2+1]-=c ; 对应图2 ,让整个a数组中绿色矩形面积的元素再减去c,使其内元素不发生改变。
b[x2+1][y1]- =c ; 对应图3 ,让整个a数组中紫色矩形面积的元素再减去c,使其内元素不发生改变。
b[x2+1][y2+1]+=c; 对应图4,,让整个a数组中红色矩形面积的元素再加上c,红色内的相当于被减了两次,再加上一次c,才能使其恢复。

我们将上述操作封装成一个插入函数:

void insert(int x1,int y1,int x2,int y2,int c)
{     //对b数组执行插入操作,等价于对a数组中的(x1,y1)到(x2,y2)之间的元素都加上了c
    b[x1][y1]+=c;
    b[x2+1][y1]-=c;
    b[x1][y2+1]-=c;
    b[x2+1][y2+1]+=c;
}

我们可以先假想a数组为空,那么b数组一开始也为空,但是实际上a数组并不为空,因此我们每次让b数组以(i,j)为左上角到以(i,j)为右下角面积内元素(其实就是一个小方格的面积)去插入 c=a[i][j],等价于原数组a中(i,j) 到(i,j)范围内 加上了 a[i][j] ,因此执行n*m次插入操作,就成功构建了差分b数组.

这叫做曲线救国。

代码如下:

  for(int i=1;i<=n;i++)
  {
      for(int j=1;j<=m;j++)
      {
          insert(i,j,i,j,a[i][j]);    //构建差分数组
      }
  }

总结

(三) 代码

#include <iostream>
using namespace std;
const int maxn = 1010;
int a[maxn][maxn], s[maxn][maxn];

void insert(int x1, int y1, int x2, int y2, int c) {
    a[x1][y1] += c;
    a[x2 + 1][y1] -= c;
    a[x1][y2 + 1] -= c;
    a[x2 + 1][y2 + 1] += c;
}

int main() {
    int m, n, q, c;
    int x1, y1, x2, y2;
    scanf("%d%d%d", &m, &n, &q);

    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            scanf("%d", &s[i][j]);
        }
    }

    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            a[i][j] = s[i][j] - s[i - 1][j] - s[i][j - 1] + s[i - 1][j - 1];
        }
    }

    while (q--) {
        scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &c);
        insert(x1, y1, x2, y2, c);
    }

    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
            printf("%d ", s[i][j]);
        }
        printf("\n");
    }

    return 0;
}

参考文献:

作者:林小鹿
链接:https://www.acwing.com/solution/content/27325/
来源:AcWing
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/739394.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

less预处理语言的运用之-变量拼接那点事

less语法的技巧总结&#xff0c;很基础&#xff0c;熟练掌握后能提高我们在大型项目中的开发效率 a:0.5; showdaw-px:100; mkcolor1:#6ec5ff; num:1; .outer{//拼接的字符串在变量后面&#xff0c;需要在冒号后面加~width:~"{showdaw-px}px";//拼接的字符串在冒号后…

Vue脚手架使用 【实战篇】

一、一个组件引用另一个组件&#x1f349; (1) 引入被引用的组件&#x1f95d; 自己创建的组件 lzq.vue 组件必须创建在components文件夹下 将自己创建的组件导入到主页面中 (2)声明该组件&#x1f95d; 本人理解&#xff1a; 声明组件可以理解为声明一个变量一样 (3)使用组…

【sql注入-报错注入2】GTID_SUBTRACT()函数 报错注入

目录 GTID_SUBTRACT()报错注入 一、语法介绍&#xff1a; 二、报错原因 网络安全小圈子 &#xff08;***注&#xff1a;注意看版本要求&#xff09; GTID_SUBTRACT()报错注入 一、语法介绍&#xff1a; 版本&#xff1a; MySQL >5.6 GTID_SUBTRACT()函数是MySQL中的一…

Unity20223.4f1中添加Tile的方法

如图&#xff0c;按顺序选择添加Rectangular&#xff08;矩形地图&#xff09;即可&#xff0c;矩形是常规瓦片地图 除常规瓦片地图外&#xff0c;Unity 还提供 Hexagonal Point Top Tilemap 和 Hexagonal Flat Top Tilemap 瓦片地图。六角形瓦片通常用于战略类桌面游戏&#x…

vertical-align middle不生效如何修改

vertical-align middle不生效如何修改 vertical-align的定义1.在父元素中增加display:table-cell&#xff0c;vertical-align 写在在父元素中2.在父元素中增加空的span元素&#xff0c;并设置其高度为100%&#xff0c;vertical-middle居中3.父元素line-height 100% 和子元素ver…

迭代读取文件

使用 torch.utils.data.dataset.Dataset 收集数据信息&#xff0c;创建数据集。 使用 import torch.utils.data.dataloader 创建一个可以批量迭代的数据载入器&#xff0c;并通过 for 循环批量读取所有文件的数据。 import torch.utils.data.dataset as dataset import torch…

windows凭据收集

实验目的 掌握windows凭据的收集方法 实验环境 windows server 2008 实验工具 mimikatz procdump 实验原理 用户凭证获取&#xff0c;一般是指 ntlm hash 或者可以直接利用的明文密码。 实验内容 使用mimikatz获取用户信息 使用procdump获取当前用户的明文密码 实验步骤…

IDEA(java: 错误: 不支持发行版本 5)

问题描述 今天在IDEA中运行项目时&#xff0c;突然蹦出error:java:不支持发行版本5报错&#xff0c;原因是项目运行的时候&#xff0c;jdk版本与本地的版本不一致&#xff0c;我的本地jdk版本是11&#xff0c;但是项目默认成了5&#xff0c;所以不一致&#xff0c;建议根据自己…

MIT 6.S081 教材第八章内容 -- Crash recovery -- 04

MIT 6.S081 教材第八章内容 -- Crash recovery -- 02 引言什么是 File system crashFile system crash示例File system logginglog_write函数end_op函数File system recovering Log写磁盘流程File system challenges 引言 MIT 6.S081 2020 操作系统 本文为MIT 6.S081课程第八…

Python启动UDP服务,监听并接收客户端数据

可以使用Python的socket库实现UDP协议的验证&#xff0c;以下是一个简单的示例代码&#xff1a; 服务器&#xff1a; [rootlocalhost python]# cat udp_server.py import socket# 创建一个UDP socket udp_socket socket.socket(socket.AF_INET, socket.SOCK_DGRAM)# 绑定到…

springboot超市进销存系统

本次设计任务是要设计一个超市进销存系统&#xff0c;通过这个系统能够满足超市进销存系统的管理及员工的超市进销存管理功能。系统的主要功能包括&#xff1a;首页、个人中心、员工管理、客户管理、供应商管理、承运商管理、仓库信息管理、商品类别管理、 商品信息管理、采购信…

Linux离线安装docker

问题&#xff1a; service docker start /status 都会报如下错误 报错&#xff1a;docker:unrecognized service 使用docker -v也能正常显示docker版本但唯独就是不能启动成功 找了很多资料都没有一个详细的答案和步骤 试了很多方法今天终于解决&#xff0c; 对此进行做个…

前端Vue自定义精美商品分类列表组件 侧边栏商品分类组件 category组件 左边分类category 右边列表List

随着技术的发展&#xff0c;开发的复杂度也越来越高&#xff0c;传统开发方式将一个系统做成了整块应用&#xff0c;经常出现的情况就是一个小小的改动或者一个小功能的增加可能会引起整体逻辑的修改&#xff0c;造成牵一发而动全身。 通过组件化开发&#xff0c;可以有效实现…

TortoiseGit 入门指南03:提交

你现在应该已经有了一个仓库&#xff0c;在工作过程中会对项目做一些修改&#xff0c;比如添加代码、修复错误等等&#xff0c;你将不定时的将这些更改 提交&#xff08;commit&#xff09;到代码仓库。 术语 提交 是将 暂存区 内容放入 版本库 。这个过程涉及到 Git 的一些基…

Jina AI 受邀出席 WAIC 2023「科技无障碍」论坛,与行业专家共话 AI 普惠未来

7 月 6 日&#xff0c;2023 世界人工智能大会&#xff08;WAIC&#xff09;在上海世博中心及世博展览馆开幕&#xff0c;并在浦东张江、徐汇西岸设分会场&#xff0c;同步在闵行等产业集聚区开展同期活动。本届大会由上海市人民政府和国家发改委、工信部、科技部、国家网信办、…

qiankun 与vue-router 不兼容导致路由显示 undefined 问题

在路由前置守卫中监听 to 及 from 的变化&#xff0c;发现 router.push 跳转路由时&#xff0c;会发现打印出 两次以上的 to、form 对象&#xff0c;只有第一次打印的from对象是正确的&#xff0c;而后两次都是由于 qiankun 与vue-router 不兼容引起的路由守卫重复执行的问题导…

CSS word-break 详解

word-break:normal 使用浏览器默认的换行规则 <!DOCTYPE html> <html> <head> <style> p.test1 { width:11em; border:1px solid #000000; word-break:normal; } </style> </head> <body> <p class"test1">This …

构建WebRTC技术需要的后端服务

&#x1f4e2;欢迎点赞 &#xff1a;&#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff0c;赐人玫瑰&#xff0c;手留余香&#xff01;&#x1f4e2;本文作者&#xff1a;由webmote 原创&#x1f4e2;作者格言&#xff1a;新的征程&#xff0c;我们面对的不是…

【C语言】三子棋----详解

目录 前言 一、游戏规则 二、创建文件 1.test.c文件 &#x1f604;菜单函数的实现 &#x1f604;main函数的实现 &#x1f604;game游戏函数的实现 2.game.c文件 &#x1f604;书写初始化棋盘的函数&#xff1a; &#x1f604;书写打印棋盘的函数 &#x1f604;书写玩家…

iSCSI磁盘配置

iSCSI磁盘简要描述 iSCSI&#xff08;Internet Small Computer System Interface&#xff09;&#xff0c;Internet小型计算机系统接口&#xff0c;又称为IP-SAN&#xff0c;是一种基于因特网及SCSI-3协议下的存储技术。 iSCSI 可以与任意类型的 SCSI 设备进行通信。对于一个…