差分+差分矩阵(更适合新手宝宝体质)

news2024/11/18 19:27:29

快速掌握差分以及差分矩阵

文章目录

  • 快速掌握差分以及差分矩阵
    • 前言
    • 差分
      • 差分的定义【官方解释】
      • 差分自定义【跟前缀和放在一起理解】
      • 差分数组的应用
    • 题目描述
    • 差分矩阵【与前缀和矩阵进行比较】
      • 差分矩阵定义【官方解释】
      • 自定义
        • 修改操作【跟前缀和对比】
      • 题目描述
      • 代码

前言

之前我们提到了前缀和数组与前缀和矩阵,现在我们可以类比处差分矩阵,差分数组
,现在我将站在新手的角度为大家介绍,学完差分的小伙伴们也可以复习一下

差分

差分的定义【官方解释】

差分是指在数学中,对于一个数列或函数,通过计算相邻元素之间的差值来得到一个新的数列或函数。差分可以用来描述数列或函数的变化趋势或规律。

对于一个数列 {a1, a2, a3, ..., an},它的一阶差分可以表示为 {d1, d2, d3, ..., dn-1},其中 di = ai+1 - ai

对于一个函数 f(x),它的一阶差分可以表示为 f'(x) = f(x+1) - f(x)

差分可以应用于各种数学领域,如微积分、离散数学、动态规划等。它在数值计算和数据分析中也有广泛的应用,可以用来处理时间序列数据、图像处理、信号处理等问题。

差分自定义【跟前缀和放在一起理解】

对于一个数组{a1, a2, a3, ..., an},我们可以有前缀和s[N],
s[1]=a[1];
s[2]=a[2]+a[1]
s[3]=a[3]+a[2]+a[1]
............
类比对于一个数组{a1, a2, a3, ..., an}
我们有
b[1]=a[1]-a[0]
b[2]=b[2]-b[1]
b[3]=b[3]-b[2]
................
我们叫{b1, b2, b3, ..., bn}{a1, a2, a3, ..., an}的差分数组;

差分数组的应用

对差分数组的前缀和数组进行范围修改;
a[1]=b[1];
a[2]=b[1]+b[2]
a[3]=b[1]+b[2]+b[3]
........................
数组a[N]就是b[N]的前缀和数组,假设我们要对a[N],进行修改,在【l,r】的范围内加上 w,假如直接对数组 a [ N ] 进行遍历操作,那么我们的时间复杂度是 O(N);

但是我们现在有了差分数组,我们就不用对 a [N ]做直接修改了,我们从它的差分数组入手,对 b[left] 进行修改,那么 a[ i ] ,a [ i+1 ] ,a [ i+2 ], a [ i+3] …就会发生改变,但是我们不能让改变一直延续下去,所以要在 b [ right ]处进行修改 【及时进行相反的操作,这样就实现了范围修改

题目描述

输入一个长度为 n 的整数序列。

接下来输入 m个操作,每个操作包含三个整数 l,r,c,表示将序列中 [l,r]
之间的每个数加上 c

请你输出进行完所有操作后的序列。

输入格式第一行包含两个整数 n 和 m

第二行包含 n 个整数,表示整数序列。

接下来 m 行,每行包含三个整数 l,r,c,表示一个操作。

输出格式
共一行,包含 n 个整数,表示最终序列。

数据范围
1≤n,m≤100000
1≤l≤r≤n
−1000≤c≤1000
−1000≤整数序列中元素的值≤1000
输入样例:
6 3
1 2 2 1 2 1
1 3 1
3 5 1
1 6 1
输出样例:
3 4 5 3 4 2
`

#include<iostream>
using namespace std;
const int N =1e5 +7;
int a[N],b[N];
int n,m;
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        //由于是前缀和,下标要从 1 开始
        cin>>a[i];
        b[i]=a[i]-a[i-1];
    }
    while(m--){
        int l,r,c;
        cin>>l>>r>>c;
        b[l]+=c,b[r+1]-=c;
        //此处不要忘记进行相反的操作
    }
    for(int i=1;i<=n;i++){
        a[i]=b[i]+a[i-1];//重新构建前缀和
        cout<<a[i]<<' ';
    }
}

差分矩阵【与前缀和矩阵进行比较】

有关前缀和矩阵的知识请看我的另2篇博客
激光矩阵问题: https://blog.csdn.net/2302_77698668/article/details/132345058

前缀和求解k倍区间问题: https://blog.csdn.net/2302_77698668/article/details/132339559

差分矩阵定义【官方解释】

差分矩阵是指由差分操作得到的矩阵。在离散数学和图论中,差分矩阵常用于描述图的性质和图算法的设计。

对于一个无向图 G = (V, E),其中 V 是顶点集合,E 是边集合。差分矩阵 D 是一个 |V| × |V| 的矩阵,其中 |V| 表示顶点的个数。差分矩阵的定义如下:

D(i, j) = -1, if i ≠ j and (i, j) ∈ E,
degree(i), if i = j,
0, otherwise.

其中,D(i, j) 表示差分矩阵的第 i 行第 j 列的元素,degree(i) 表示顶点 i 的度数(即与顶点 i 相连的边的个数)。

差分矩阵可以用来描述图的拉普拉斯矩阵,它是一个对称半正定矩阵,具有很多重要的性质和应用。差分矩阵在图论算法中也有广泛的应用,如最短路径算法、最小生成树算法、图分割算法等。

自定义

跟之前一样,我们继续类比推理
a [i] [j] 矩阵【 b[1] [1](左上端点),b[i][j] 右下端点】的和
那么要对 a [ i ] [ j ]进行范围修改,我们就只需要对 b[N][N]进行修改

修改操作【跟前缀和对比】

在这里插入图片描述
在这里插入图片描述
为啥差分是从后面开始进行面积加减呢?
想想我们之前提到的

但是我们现在有了差分数组,我们就不用对 a [N ]做直接修改了,我们从它的差分数组入手,对 b[left] 进行修改,那么 a[ i ] ,a [ i+1 ] ,a [ i+2 ], a [ i+3] …就会发生改变,但是我们不能让改变一直延续下去,所以要在 b [ right ]处进行修改 【及时进行相反的操作,这样就实现了范围修改

差分会对后面的前缀和数组造成影响,对前面的不会影响,一维的数组适用,二维的数组同样适用

题目描述

输入一个 n 行 m 列的整数矩阵,再输入 q
个操作,每个操作包含五个整数 x1,y1,x2,y2,c,其中 (x1,y1)
和 (x2,y2) 表示一个子矩阵的左上角坐标和右下角坐标。

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

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

输入格式
第一行包含整数 n,m,q接下来 n 行,每行包含 m
个整数,表示整数矩阵。

接下来 q 行,每行包含 5 个整数 x1,y1,x2,y2,c,表示一个操作。

输出格式
共 n 行,每行 m 个整数,表示所有操作进行完毕后的最终矩阵。

数据范围
1≤n,m≤1000
1≤q≤100000
1≤x1≤x2≤n
1≤y1≤y2≤m
−1000≤c≤1000
−1000≤矩阵内元素的值≤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
直接上代码

代码

#include<iostream>
using namespace std;
const int N =1e3 +7;
int a[N][N],b[N][N];
int n,m,q;
//这里是对 b 数组进行操作,相当于在(x1,y1)->(x2,y2)范围内加上c
void add(int x1,int y1,int x2,int y2,int c){
    b[x2+1][y2+1]+=c;
    b[x1][y1]+=c;
    b[x2+1][y1]-=c;
    b[x1][y2+1]-=c;
    //这里的操作可以参考之前关于差分的描述 
}
int main(){
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
            add(i,j,i,j,a[i][j]);
            //通过这个操作只会对 b[i][j]
            //那个点产生影响
        }
    }
    
    while(q--){
        int x1,y1,x2,y2,c;
        cin>>x1>>y1>>x2>>y2>>c;
        add(x1,y1,x2,y2,c);
        
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1];
            //这个是前缀和矩阵的计算公式,建议和之前的一维数组类比一下
            cout<<b[i][j]<<' ';
        }
        puts("");
    }
    return 0;
}

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

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

相关文章

微信小程序——小程序的API介绍

小程序的宿主环境-API 1.小程序API概述 小程序中的API是由宿主环境提供的&#xff0c;通过这些丰富的小程序API&#xff0c;开发者可以方便的调用微信提供的能力&#xff0c;例如&#xff1a;获取用户信息&#xff0c;本地存储&#xff0c;支付功能等。 2.小程序API的3大分类…

wav文件碎片多删除后恢复案例

wav是微软针对音频提供的一种文件&#xff0c;其本质上和qt类文件&#xff08;如mp4 mov&#xff09;是一样的&#xff0c;都是“容器”类文件。但凡是容器类的文件其关注的点就是制定规则&#xff0c;一切按规则来&#xff08;wav中就是速率、时长、编码类型等&#xff09;。这…

Linux下利用文件IO函数完成多进程复制图片,父进程复制前一半,子进程复制后一半

Linux下利用文件IO函数完成多进程复制图片&#xff0c;父进程复制前一半&#xff0c;子进程复制后一半 一 、概述 在Linux环境下&#xff0c;利用多进程完成图片的复制操作本demo用到了两个进程&#xff0c;一个是主函数所在的父进程&#xff0c;一个在主函数里面创建的子进程…

安装系统作为启动盘的U盘恢复原样

1、插U盘 2、winr——cmd&#xff0c;输入diskpart 3、此电脑——管理——磁盘管理——查看磁盘号&#xff1a;磁盘 1 4、输入&#xff1a;select disk 1——clean 5、磁盘管理——右击新建简单卷——下一步即可

u盘传输数据的时候拔出会怎么样?小心这些危害

U盘是我们日常生活和工作中常使用的一种便携式存储设备。然而&#xff0c;在使用U盘传输数据时&#xff0c;有时我们会不小心将它拔出&#xff0c;而这个看似微不足道的行为实际上可能会带来严重的后果。本文将向您介绍U盘在传输数据时突然拔出可能导致的各种危害&#xff0c;其…

如何恢复U盘里面的已经损坏的数据?

弹出使用驱动器之前&#xff0c;先将U盘格式化的信息框&#xff0c;是Windows系统针对某些特定类型的U盘或移动硬盘的一种常见处理方式。一般来说&#xff0c;如果U盘或移动硬盘出现某些故障或问题&#xff0c;Windows系统会建议用户将其格式化。 格式化是一种常规的操作&…

Kafka消费者组重平衡(二)

文章目录 概要重平衡通知机制消费组组状态消费端重平衡流程Broker端重平衡流程 概要 上一篇Kafka消费者组重平衡主要介绍了重平衡相关的概念&#xff0c;本篇主要梳理重平衡发生的流程。 为了更好地观察&#xff0c;数据准备如下&#xff1a; kafka版本&#xff1a;kafka_2.1…

9.12 C++作业

实现一个图形类&#xff08;Shape&#xff09;&#xff0c;包含受保护成员属性&#xff1a;周长、面积&#xff0c; 公共成员函数&#xff1a;特殊成员函数书写 定义一个圆形类&#xff08;Circle&#xff09;&#xff0c;继承自图形类&#xff0c;包含私有属性&#xff1a;半…

模拟信号电压或电流信号转变频器频率传感器信号隔离变送器0-5V/0-10V/0-20mA/4-20mA转0-5KHz/0-10KHz/1-5KHz

主要特性: 精度等级&#xff1a;0.1 级、0.2 级。产品出厂前已检验校正&#xff0c;用户可以直接使用输 入 &#xff1a;0-5V/0-10V/1-5V,0-10mA/0-20mA/4-20mA 等输出信号&#xff1a;0-5KHz/0-10KHz/1-5KHz 等标准信号辅助电源&#xff1a;5V、9V、12V、15V 或 24V 直流单电…

OpenCV(四十三):Shi-Tomas角点检测

1.Shi-Tomas角点检测原理 Shi-Tomasi&#xff08;也称为Good Features to Track&#xff09;角点检测算法是一种改进的角点检测方法&#xff0c;它基于Harris角点检测算法&#xff0c;并针对一些不足进行了改进。 与Harris角点检测不同&#xff0c;Shi-Tomasi使用了更简化的角点…

PDF怎么合并?这几个方法收藏起来吧

PDF文件是一种非常常见的文档格式&#xff0c;它具有跨平台、易于阅读和打印等优点&#xff0c;因此在生活和工作中得到了广泛的应用。当我们需要将多个PDF文件合并成一个文件时&#xff0c;我们可以采用以下几种方法。 方法一&#xff1a;使用PDF转换工具 我们在电脑上打开迅…

Spring Boot 中的 @CacheEvict 注解使用

Spring Boot 中的 CacheEvict 注解 在 Spring Boot 中&#xff0c;缓存是提高应用性能的重要手段。为了更好地管理缓存&#xff0c;Spring Boot 提供了一系列的缓存注解&#xff0c;其中 CacheEvict 注解用于清空缓存。 本文将介绍 CacheEvict 注解的含义、原理以及如何使用。…

华为云云耀云服务器L实例评测-基于华为云服务器的测试及简单配置

引言 云计算已经成为现代企业和个人的重要组成部分。在云计算市场上&#xff0c;华为云一直以来都以其出色的性能和服务质量而闻名。周末的时候&#xff0c;利用华为云云耀云服务器搭建了一个基于hexo的个人博客&#xff0c;我用的是2核2G的3M带宽的配置&#xff0c;访问起来挺…

自动化搭建(Jenkins_Docker)1

简介 目前为了搭建Android自动化构建&#xff0c; 包含自动打包、代码审查工具以及自动化测试的串联。如下图&#xff1a; 我拿到的是一个2T的一个服务器&#xff0c;需要在上面搭建整个环境&#xff0c; 整体分解如下&#xff1a; Java安装Jenkins安装和配置Gerrit 和 rep…

GIS前端—地图标注

GIS前端—地图标注 地图标注原理图片标注文本标注矢量图形标注 地图标注原理 地图标注是将空间位置信息点与地图关联&#xff0c;通过图标、窗口等形式把点相关的信息展现在地图上。地图标注是WebGIS应用的核心功能之一&#xff0c;在大众应用中十分常见。基于地图标注可以为用…

使用代码产生标准的软件架构图之C4

在软件开发的流程中&#xff0c; 软件架构图是重要的软件文档&#xff0c;软件架构图包含有多个层级&#xff0c;最常见的&#xff0c;有软件的整体架构和组件、类等图。 整体架构可能使用PPT或者一些绘图工具Visio来绘制组件、类等图有UML的标准&#xff0c; 也可以使用Visio…

【Android知识笔记】进程通信(二)

一、Binder对象是如何跨进程传递的 binder传递有哪些方式?binder在传递过程中是怎么存储的?binder对象序列化和反序列化过程?binder对象传递过程中驱动层做了什么?总结 Binder 对象的跨进程传递主要靠 Parcel 的两个关键方法 writeStrongBinder() 和

【数据结构】—堆排序以及TOP-K问题究极详解(含C语言实现)

食用指南&#xff1a;本文在有C基础的情况下食用更佳 &#x1f525;这就不得不推荐此专栏了&#xff1a;C语言 ♈️今日夜电波&#xff1a;ルミネセンス—今泉愛夏 1:01 ━━━━━━️&#x1f49f;──────── 5:05 …

[刷题记录]牛客面试笔刷TOP101(一)

牛客笔试算法必刷TOP101系列,每日更新中~(主要是记录自己的刷题,所以描述的可能不是很清楚 但如果刚好能帮助到你就更好了) 后续后头复习的时候,记得是看正解啊,别对着错的例子傻傻看了... 目录 1.合并有序链表2023.9.3 2.链表是否有环2023.9.4 3.判断链表中环的入口点 …

学Python的漫画漫步进阶 -- 第三步

学Python的漫画漫步进阶 -- 第三步 三、数字类型的数据3.1 Python中的数据类型3.2 整数类型3.3 浮点类型3.4 复数类型3.5 布尔类型3.6 数字类型的相互转换3.6.1 隐式类型的转换3.6.2 显式类型的转换 3.7 练一练3.8 数字类型的总结全部16步完成后 &#xff0c;后续就是介绍项目实…