差分详细讲解(C++)

news2025/2/3 22:08:34

每日一句:平凡的我在人多的地方曾极力小心翼翼, 但不知从何时起 ,我不太在意别人的目光了。比起被人觉得是个怪人,我现在更害怕浪费时间。

差分

  • 一、一维差分
  • 二、二维差分


一、一维差分

差分就是前缀和的逆运算,如果你不懂什么是前缀和,看这里->前缀和详解

数组a:a[1], a[2], a[3], a[n]
数组b : b[1] ,b[2] , b[3], b[i]
使得 a数组是b数组的前缀和,b数组是a数组的差分
a[i] = b[1] + b[2] + …+ b[i]

数字来看的话就是这样的:
a数组1 3 7 5 2
b数组1 2 4 -2 -3
Sumb数组1 1+2 1+2+4 1+2+4-2 1+2+4-2-3
----------也就是1 3 7 5 2跟原数组还是相同的
a是b的前缀和,b是a的差分.

那么,问题来了,差分有什么用呢?

当你把一个区间[L,R]的数都加上或减去某一个数x的时候,该怎末做呢?第一时间想到的肯定是暴力做法,输入LR区间,然后for循环,直接暴力解决,确实暴力解法能解决很多事情,但是时间复杂度很高,为O(n),如果想进行m次区间加上或减去x的操作呢?每次都遍历LR区间,那么时间复杂度就更高了O(n*m).这个时候,就有人对其优化,想出来了一种名为差分的解法,差分解法呢,有一个公式:[L,R] + X <==>差分数组[L] + X,差分数组[R+1] - X;
那么,这个公式是怎么来的?
在这里插入图片描述
下面看一道例题:

输入一个长度为 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

1.先输入数组

	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
	}

然后把原数组a,变成差分数组b

	void insert(int l, int r, int c)
	{
		b[l] += c;
		b[r + 1] -= c;
	}


	for (int i = 1; i <= n; i++)
	{
		insert(i, i, a[i]);
	}

对差分数组进行m次操作

	while (m--)
	{
		int l, r, c;
		cin >> l >> r >> c;
		insert(l, r, c);
	}

最后,将差分数组变回原数组

	for (int i = 1; i <= n; i++)
	{
		b[i] += b[i - 1];
		cout << b[i] << ' ';
	}

总代码

#include <iostream>

using namespace std;

const int N = 1e6 + 10;

int a[N];

int b[N];

void insert(int l, int r, int c)
{
	b[l] += c;
	b[r + 1] -= c;
}

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
	}

	for (int i = 1; i <= n; i++)
	{
		insert(i, i, a[i]);
	}

	while (m--)
	{
		int l, r, c;
		cin >> l >> r >> c;
		insert(l, r, c);
	}

	for (int i = 1; i <= n; i++)
	{
		b[i] += b[i - 1];
		cout << b[i] << ' ';
	}


	return 0;
}

题目来源acwing799

二、二维差分

二维差分也就是二维前缀和的逆运算,其构造差分的过程和构造一维差分的过程差不多类似.在这里主要说一下构造过程:

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

标红区区域便是x1,y1进行区间加或减操作的区域

在这里插入图片描述

黄色和咖啡色区域便是x2+1,y1和x1,y2+1的区间,而有x2+1,y2+1的区间是重叠的部分,也就是说,在 b[x2 + 1][y1] -= c; b[x1][y2 + 1] -= c;这两部中,x2+1,y2+1被多减了一次,所以要把这部分还回去,也就是这一步 b[x2 + 1][y2 + 1] += c;

在这里插入图片描述

下面看一到例题

输入一个 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 = 1010;

int n, m, q;
int a[N][N], b[N][N];

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

int main()
{
    scanf("%d%d%d", &n, &m, &q);

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

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            insert(i, j, i, j, a[i][j]);

    while (q--)
    {
        int x1, y1, x2, y2, c;
        cin >> x1 >> y1 >> x2 >> y2 >> c;
        insert(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];

    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++) printf("%d ", b[i][j]);
        puts("");
    }

    return 0;
}

题目来源acwing800

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

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

相关文章

移动技术在仓库运营管理中的作用

作者&#xff1a;Mike Kay&#xff0c;Mendix公司合作伙伴The Config Team渠道客户经理 市面上出现越来越多的仓库管理系统&#xff08;WMS&#xff09;以满足企业更好地管理供应链的需求。想要充分挖掘WMS的优点&#xff0c;一般可以通过移动解决方案来将关键的供应链运作进…

浪潮信息工程师:带你了解设备透传虚拟机的快速启动技术优化方案

编者按&#xff1a;将物理设备通过 vfio 透传给虚拟机是虚拟化常用的技术&#xff0c;但当为虚拟机分配比较大的内存时&#xff0c;虚拟机的启动时间会明显变慢&#xff0c;可能由十几秒延长至数分钟&#xff0c;严重影响用户使用体验。本文整理自龙蜥大讲堂 51 期&#xff0c;…

小林coding阅读笔记:计算机网络基础篇-TCP\IP模型

前言 参考/导流&#xff1a; 小林coding - 2.1 TCP/IP 网络模型有哪几层&#xff1f;学习意义 学习分层设计思想构建网络层次以及各层协议作用知识体系为网络编程奠定理论基础&#xff0c;对于RPC框架or分布式系统通信都是极为重要的一节&#xff0c;是提升整个系统效率的关键…

ubunt配置samba服务器,匿名访问

1. 环境 ubuntu14.04 2. 安装samba服务器 sudo apt-get install samba 3. 配置samba文件 vim /etc/samba/smb.conf 在最后添加如下内容 [muchx]comment Shared Folder with username and passwordpath /home/muchx/sharepublic yeswritable yesvalid users muchxcre…

二、基于kubeadm安装kubernetes1.25集群第一篇

1、概述 Kubeadm 是一个提供了 kubeadm init 和 kubeadm join 的工具&#xff0c; 作为创建 Kubernetes 集群的 “快捷途径” 的最佳实践。 kubeadm 通过执行必要的操作来启动和运行最小可用集群。 按照设计&#xff0c;它只关注启动引导&#xff0c;而非配置机器。同样的&…

虹科分享 | 硬件加密U盘 | 管理密码安全的四大工具

随着网络攻击变得越来越突出&#xff0c;密码安全变得越来越重要。为了为每个帐户创建安全密码&#xff0c;许多人正在转向密码管理工具来帮助防止敏感数据的泄露。 考虑到这一点&#xff0c;以下是一些顶级密码管理工具。 领先的密码管理工具 Keeper密码管理器和数字保险库 …

kali linux手动编译网卡驱动(以mt7612u为例)

〇、linux常用命令 《Linux入门与基础》课程教案_小王小王指定辉煌的博客-CSDN博客_linux入门与基础教案 linux常用命令笔记&#xff08;二&#xff09;_小王小王指定辉煌的博客-CSDN博客 一、下载源码 查看系统版本号 uname -r uname -a cat /proc/version 或/lib/module…

手撕红黑树的构建与验证

上篇文章我们介绍了AVL树的构建与适用场景&#xff0c;我们知道了AVL树虽然查找效率很高&#xff0c;但是不适合频繁插入或删除的场景。为了解决这个问题又诞生了新的数据结构&#xff1a;红黑树 那么本篇文章就着重介绍红黑树的性质与如何构建。 1.红黑树的性质 1.结点颜色非黑…

邓俊辉 《数据结构》笔记1 绪论

邓俊辉 《数据结构》笔记1 绪论 CSDN转图床总是崩&#xff0c;如果全写完再上传一次要调好多&#xff0c;感觉很麻烦&#xff0c;所以写一点更新一点&#xff0c;会持续更新 提前发出来还有个好处就是push自己更新不会咕咕咕&#xff0c;哈哈 参考资料 MOOC 数据结构上MOOC 数…

【计算机考研408】磁盘的初始化过程

该图是磁盘物理图 关于磁盘存储器&#xff0c;[柱面号盘面号扇区号]⇔外存块号 注&#xff1a;柱面是相对位置相同的磁道所构成的面 磁盘初始化 低级初始化&#xff08;也称物理格式化&#xff09; &#xff08;1&#xff09;分扇区 &#xff08;2&#xff09;用特殊数据结构…

linux后台自定义后台服务service(以filebeat举例)

文章目录一、配置攥写1&#xff09;安装filebeat和配置相关修改2&#xff09;常用命令二、启动顺序1&#xff09;命令循序2&#xff09;systemctl添加自定义系统服务&#xff08;服务填写指南&#xff09;3&#xff09;linux的systemctl命令详解及使用教程三、遇到的坑点和报错…

谁再要你自学网络安全,请给他一大B兜

前言 作为一名6年网安工程师老菜鸟来说&#xff0c;我实在想不通&#xff0c;开发岗位那么多&#xff0c;为什么要来学网安? 在这里必须给那些准备入坑的同学泼几盆冷水&#xff01;零基础自学网络安全&#xff1f;劝你还是别做梦了&#xff01; 基础确实很简单&#xff0c…

2023火爆共享购商业模式概念、框架、基础制度

各位企业家及创业者朋友们&#xff0c;你们好。我是微三云&#xff08;陈志坤&#xff09;&#xff0c;在你打开这个文章的时候&#xff0c;先不要急&#xff0c;因为任何一个能够长久、安稳、盈利的平台&#xff0c;背后肯定有一位看准宏观方向且耐心的人。这是一个极具颠覆性…

算法图论篇

文章目录一、DFS1.排列数字&#xff08;全排列&#xff09;2.n皇后3.树的重心二、BFS1.走迷宫2.八数码3.图中点的层次三、拓扑排序1.有向图的拓扑序列四、最短路1.Dijkstra2. bellman-ford3.spfa4.floyd五、求最小生成树1.Prim算法2.Kruskal算法六、二分图1.染色法判定二分图2.…

UWB汽车钥匙介绍

汽车钥匙经历了机械钥匙、遥控钥匙、PEPS、数字钥匙四个阶段&#xff0c;而数字钥匙又分为BLE/NFC/UWB三种技术路线。 由于UWB安全性、定位精度、作用范围明显好于BLE和NFC&#xff0c;因此成为汽车数字钥匙的最优技术。 PEPS与数字钥匙: PEPS是指无钥匙进入/无钥匙启动系统&a…

【爬虫】JS调试解决反爬问题系列2

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作&#xff0c;主要擅长领域有&#xff1a;爬虫、后端、大数据…

ubuntu arm架构各版本源整理

目录 一、x86机构 1、ubuntu 20.04 2、ubuntu 18.04 3、ubuntu 21.10 4、ubuntu 22.04 二、arm机构 1、ubuntu 20.04 2、ubuntu 18.04 3、ubuntu 21.10 4、ubuntu 22.04 三、出现的问题 1、换成国内源后报https证书问题 2、如果选择国内开源站 ​3、提示the publi…

C语言重点解剖操作符要点速记

1.在多层嵌套的时候&#xff0c;每一次}结束加一个注释&#xff0c;标记清楚结束的是哪一个。 2.大部分注释都换成了空格。 in/* */t a; 等价于 in t a;替换成一个空格。 3.# define(中间可以有空格)&#xff0c;但是不建议。 4.全局变量&#xff0c;常量定义等建议加上注释…

基于昇思MindSpore Quantum,实现量子虚时演化算法

01、关于昇思MindSpore项目介绍 1.项目名称 基于昇思MindSpore Quantum&#xff0c;实现量子虚时演化算法 2.项目链接 https://summer-ospp.ac.cn/#/org/prodetail/221cb0176 3.项目描述 在本次项目中&#xff0c;我们将运用MindSpore Quantum框架在量子线路上完成虚时演…

【Django】第一课 银行账户管理系统开发

概念 django服务器开发框架是一款基于Python编程语言用于web服务器开发的框架&#xff0c;采用的是MTV架构模式进行分层架构。 项目的搭建 1.打开pycharm开发软件&#xff0c;打开开发软件的内置dos窗口操作命令行 在这里指定项目存放的磁盘路径&#xff0c;并使用创建djang…