领略算法真谛:差分

news2025/2/12 3:08:42

嘿,各位技术潮人!好久不见甚是想念。生活就像一场奇妙冒险,而编程就是那把超酷的万能钥匙。此刻,阳光洒在键盘上,灵感在指尖跳跃,让我们抛开一切束缚,给平淡日子加点料,注入满满的passion。准备好和我一起冲进代码的奇幻宇宙了吗?Let's go!

我的博客:yuanManGan

我的专栏:C++入门小馆 C言雅韵集 数据结构漫游记  闲言碎语小记坊 题山采玉

目录

差分

⼀维差分

题目理解:

思路讲解:

代码实现:

⼆维差分

题目理解:

思路讲解:

代码展示:

练习题:

答案:


差分

前缀和与差分的核⼼思想是预处理,可以在暴⼒枚举的过程中,快速给出查询的结果,从⽽优化时间 复杂度。 是经典的⽤空间替换时间的做法。
学完差分之后,⼤家会发现,前缀和与差分是⼀对互逆的运算。

差分主要是用于对一个区间整体加或者减去同一个数这类问题,这里还是以一道题为例子展开吧

⼀维差分

题⽬来源: ⽜客⽹
题⽬链接: 【模板】差分
难度系数: ★

题目理解:

给了一个长度为n的数组,要求对数组 l 到 r 区间进行加上 k 的处理进行m次,然后输出数组的所有元素。

思路讲解:

暴力解法:

要求对那个区间进行操作我们就一次for循环加上k就行了,但时间复杂度为m*n(1e5 * 1e5)显然会超时,这时我们就引出了差分数组

差分:

我们依旧像前缀和一样,创建一个差分数组,这里存储的不再是前缀和,而是这一位元素减去上一位元素的值

这就是一个差分数组,但我们要解决题目,这个差分数组有什么用呢?别急,我们先对原数组一个区间加上一个数,发现差分数组只改变了两个数,时间复杂度就从O(n)变成了O(1)了。

我们如果要在x~y区间加上k,就等价于a[x] += k , a[ y  + 1] -= k.只需要改变这两个数就可以解决问题了。

心急的朋友这时又要问了,那我怎么还原原数组呢,我们仅需要对差分数组求前缀和就解决问题了,是不是很奇妙呢,所以说差分与前缀和互为逆运算。

代码实现:

#include<iostream>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int n, m;
//差分数组
LL f[N];
int main()
{
	cin >> n >> m;
	//预处理
	for (int i = 1; i <= n; i++)
	{
		LL x; cin >> x;
		f[i] += x;
		f[i + 1] -= x;
	}
	//进行m次操作
	while (m--)
	{
		int l, r, k; cin >> l >> r >> k;
		f[l] += k, f[r + 1] -= k;
	}
	//对差分数组求前缀和还原
	for (int i = 1; i <= n; i++)
	{
		f[i] += f[i - 1];
		cout << f[i] << " ";
	}

	return 0;
}

⼆维差分

直接上题目:
题⽬来源: ⽜客⽹
题⽬链接: 【模板】⼆维差分
难度系数: ★

题目理解:

给了个二维数组,要求对以(x1, y1)为左上角,(x2,y2)为右下角的子矩阵的每个元素都加上k,进行q次操作,最后输出数组

思路讲解:

暴力解法:

叫你加你就加,老老实实最后换来时间复杂度:O(n * m * q) = 1e4 * 1e4 * 1e5。时间复杂度都上天了。

二维差分:

差分数组的初始化先别忙着讲,先解决对以(x1, y1)为左上角,(x2,y2)为右下角的子矩阵的每个元素都加上k,这个问题,然后x1 = x2,y1 = y2, k = x,不就解决了差分数组初始化的问题了吗?

这是原数组,我们像实现如图的功能 。

我们从一维数组了解到,对差分数组求前缀和能得到原始数组,那我们不妨假设一个差分数组对任意位置加上一个k试试

然后我们对这个数组求前缀和,发现以x1,y1为左上角的矩阵的前缀和都受到了影响,都加上了k。

但我们只需但我们只需要对 以(x1, y1)为左上角,(x2,y2)为右下角的子矩阵的每个元素都加上k,我们再把边上的减去就成了:

发现就差一点就能完成任务了,最后将x2 + 1, y2 + 1位置加上k就大功告成了!

代码展示:

#include <iostream>

using namespace std;

typedef long long LL;

const int N = 1e4 + 10;

//差分数组
LL f[N][N];

int n, m, q;
//添加k操作
void insert(LL x1, LL y1, LL x2, LL y2, LL k)
{
	f[x1][y1] += k; f[x2 + 1][y2 + 1] += k;
	f[x1][y2 + 1] -= k; f[x2 + 1][y1] -= k;
}
int main()
{
	cin >> n >> m >> q;
	//预处理差分数组
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++)
		{
			LL x; cin >> x;
			insert(i, j, i, j, x);
		}
	}
	//进行q次操作
	while (q--)
	{
		int x1, y1, x2, y2, k;
		cin >> x1 >> y1 >> x2 >> y2 >> k;
		insert(x1, y1, x2, y2, k);
	}
	//前缀和差分数组还原原数组
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++)
		{
			f[i][j] += f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1];
			cout << f[i][j] << " ";
		}
		cout << endl;
	}
}

练习题:

一维差分:

海底高铁

二维差分:

地毯 

答案:

海底高铁:

#include<iostream>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int n, m;
LL f[N];
int main()
{
	cin >> n >> m;
	int x; cin >> x;
	for (int i = 2; i <= m; i++)
	{
		int y; cin >> y;
		if (x > y) f[x]--, f[y]++;
		else f[y]--, f[x]++;
		x = y;
	}
	//还原原数组
	for (int i = 1; i <= n; i++) f[i] += f[i - 1];
	LL ret = 0;
	for (int i = 1; i < n; i++)
	{
		int a, b, c; cin >> a >> b >> c;
		ret += min(a * f[i], c + b * f[i]);
	}
	cout << ret << endl;
	return 0;
}

地毯:

#include<iostream>
using namespace std;
const int N = 1010;
int n, m;
int f[N][N];
int main()
{
	cin >> n >> m;
	while (m--)
	{
		int x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2;
		f[x1][y1]++; f[x2 + 1][y1]--; 
		f[x1][y2 + 1]--; f[x2 + 1][y2 + 1]++;
	}
	//还原
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
		{
			f[i][j] += f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1];
			cout << f[i][j] << " ";
		}
		cout << endl;
	}
	return 0;
}

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

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

相关文章

【图片转换PDF】多个文件夹里图片逐个批量转换成多个pdf软件,子文件夹单独合并转换,子文件夹单独批量转换,基于Py的解决方案

建筑设计公司在项目执行过程中&#xff0c;会产生大量的设计图纸、效果图、实景照片等图片资料。这些资料按照项目名称、阶段、专业等维度存放在多个文件夹和子文件夹中。 操作需求&#xff1a;为了方便内部管理和向客户交付完整的设计方案&#xff0c;公司需要将每个项目文件…

在Linux上如何让ollama在GPU上运行模型

之前一直在 Mac 上使用 ollama 所以没注意&#xff0c;最近在 Ubuntu 上运行发现一直在 CPU 上跑。我一开始以为是超显存了&#xff0c;因为 Mac 上如果超内存的话&#xff0c;那么就只用 CPU&#xff0c;但是我发现 Llama3.2 3B 只占用 3GB&#xff0c;这远没有超。看了一下命…

程序诗篇里的灵动笔触:指针绘就数据的梦幻蓝图<8>

大家好啊&#xff0c;我是小象٩(๑ω๑)۶ 我的博客&#xff1a;Xiao Xiangζั͡ޓއއ 很高兴见到大家&#xff0c;希望能够和大家一起交流学习&#xff0c;共同进步。 今天我们复习前面学习的指针知识 目录 关于指针数组和数组指针的区别指针数组&#xff08;Array of Poi…

快速集成DeepSeek到项目

DeepSeek API-KEY 获取 登录DeekSeek 官网&#xff0c;进入API 开放平台 2. 创建API-KEY 复制API-KEY进行保存&#xff0c;后期API调用使用 项目中集成DeepSeek 这里只展示部分核心代码&#xff0c;具体请查看源码orange-ai-deepseek-biz-starter Slf4j AllArgsConstructo…

DeepSeek做赛车游戏

赛车模型 2D生成图片 任意AI图片软件SD&#xff0c;MJ 图片生成3D模型 车身 车轮 场景 Rodin,Tripo和Meshy 询问deepSeek如何开发 拷贝代码 将汽车运行代码拖到汽车上 再让AI写个摄像头跟随代码 再去提问deepseek控制轮胎和一些处理细节

未来替代手机的产品,而非手机的本身

替代手机的产品包括以下几种&#xff1a; 可穿戴设备&#xff1a;智能手表、智能眼镜等可穿戴设备可以提供类似手机的功能&#xff0c;如通话、信息推送、浏览网页等。 虚拟现实&#xff08;VR&#xff09;技术&#xff1a;通过佩戴VR头显&#xff0c;用户可以进行语音通话、发…

uniapp开发微信小程序请求超时设置【亲测有效】

在Hbuilderx中 使用uniapp开发微信小程序时 封装请求方法 请求代码如下 function requestFun(app) {// get请求app.config.globalProperties._get function(path, data, success, fail, complete) {data data || {};data.token uni.getStorageSync(token) || ;uni.request…

deepseek本地部署-linux

1、官网推荐安装方法&#xff08;使用脚本&#xff0c;我绕不过github&#xff0c;未采用&#xff09; 登录ollama下载网站https://ollama.com/download/linux&#xff0c;linux下有下载脚本。 正常来说&#xff0c;在OS系统下直接执行脚本即可。 2、手动安装方法 2.1获取ol…

vite + axios 代理不起作用 404 无效

vite axios 代理不起作用 先看官方示例 export default defineConfig({server: {proxy: {// 字符串简写写法/foo: http://localhost:4567,// 选项写法/api: {target: http://jsonplaceholder.typicode.com,changeOrigin: true,rewrite: (path) > path.replace(/^\/api/, )…

【Linux】从零开始:编写你的第一个Linux进度条小程序

Linux相关知识点可以通过点击以下链接进行学习一起加油&#xff01;初识指令指令进阶权限管理yum包管理与vim编辑器GCC/G编译器make与Makefile自动化构建GDB调试器与Git版本控制工具 &#x1f308;个人主页&#xff1a;是店小二呀 &#x1f308;C语言专栏&#xff1a;C语言 &am…

【办公类-53-04】20250209Python模仿制作2024学年第二学期校历

背景需求&#xff1a; 马上开学了&#xff0c;又要制作校历&#xff08;删划节假日&#xff09;。之前我都是用网络的图片&#xff0c;然后在PPT里修改。 存在问题&#xff1a; 网络校历是从周日开始的&#xff0c;但日常我们老师做教案&#xff0c;都是默认从周一到周五&…

11vue3实战-----封装缓存工具

11vue3实战-----封装缓存工具 1.背景2.pinia的持久化思路3.以localStorage为例解决问题4.封装缓存工具 1.背景 在上一章节&#xff0c;实现登录功能时候&#xff0c;当账号密码正确&#xff0c;身份验证成功之后&#xff0c;把用户信息保存起来&#xff0c;是用的pinia。然而p…

Unity 基础编程

在这个练习中将新建unity脚本&#xff0c;控制player的运动与转动&#xff0c;实现用代码检测碰撞与删除物体。 该练习将应用附件中的项目文件&#xff0c;该文件与Unity快速练习的文件是同一个项目文件。 一、构建Player运动脚本 该部分将构建一个在场景中由玩家控制游戏物…

Spring Boot接入Deep Seek的API

1&#xff0c;首先进入deepseek的官网&#xff1a;DeepSeek | 深度求索&#xff0c;单击右上角的API开放平台。 2&#xff0c;单击API keys&#xff0c;创建一个API&#xff0c;创建完成务必复制&#xff01;&#xff01;不然关掉之后会看不看api key&#xff01;&#xff01;&…

从Word里面用VBA调用NVIDIA的免费DeepSeekR1

看上去能用而已。 选中的文字作为输入&#xff0c;运行对应的宏即可&#xff1b;会先MSGBOX提示一下&#xff0c;然后相关内容追加到word文档中。 需要自己注册生成好用的apikey Option ExplicitSub DeepSeek()Dim selectedText As StringDim apiKey As StringDim response A…

C语言学习笔记:子函数的调用实现各个位的累加和

在C语言程序学习之初&#xff0c;我们都会学习如何打印 hello world&#xff0c;在学习时我们知道了int main&#xff08;&#xff09;是主函数&#xff0c;程序从main函数开始执行&#xff0c;这是流程控制的一部分内容。在主函数中我们想要实现一些功能&#xff0c;比如求各个…

grafana面板配置opentsdb

新增面板&#xff1a; 这里add-panel: 如果不是想新增面板而是想新增一行条目&#xff0c;则点击convert to row: 在新增的面板这里可以看到选择数据源 Aggregator&#xff1a;聚合条件&#xff0c;区分下第一行和第二行的aggregator&#xff0c;第一个是对指标值的聚合&…

2025年02月10日Github流行趋势

项目名称&#xff1a;dify 项目地址url&#xff1a;https://github.com/langgenius/dify项目语言&#xff1a;TypeScript历史star数&#xff1a;64707今日star数&#xff1a;376项目维护者&#xff1a;takatost, crazywoola, laipz8200, iamjoel, JohnJyong项目简介&#xff1a…

Ansible简单介绍及用法

一、简介 Ansible是一个简单的自动化运维管理工具&#xff0c;基于Python语言实现&#xff0c;由Paramiko和PyYAML两个关键模块构建&#xff0c;可用于自动化部署应用、配置、编排task(持续交付、无宕机更新等)。主版本大概每2个月发布一次。 Ansible与Saltstack最大的区别是…

渗透利器工具:Burp Suite 联动 XRAY 图形化工具.(主动扫描+被动扫描)

Burp Suite 联动 XRAY 图形化工具.&#xff08;主动扫描被动扫描&#xff09; Burp Suite 和 Xray 联合使用&#xff0c;能够将 Burp 的强大流量拦截与修改功能&#xff0c;与 Xray 的高效漏洞检测能力相结合&#xff0c;实现更全面、高效的网络安全测试&#xff0c;同时提升漏…