【算法通关指南:算法基础篇(三)】一维差分专题:1.【模板】差分 2.海底高铁

🔥小龙报:个人主页

🎬作者简介:C++研发,嵌入式,机器人方向学习者

❄️个人专栏:《算法通关指南》
永远相信美好的事情即将发生


文章目录


前言

本专栏聚焦算法题实战,系统讲解算法模块:以《c++编程》,《数据结构和算法》《基础算法》《算法实战》 等几个板块以题带点,讲解思路与代码实现,帮助大家快速提升代码能力
ps:本章节题目分两部分,比较基础笔者只附上代码供大家参考,其他的笔者会附上自己的思考和讲解,希望和大家一起努力见证自己的算法成长


一、差分

前缀和与差分的核心思想是预处理,可以在暴力枚举的过程中,快速给出查询的结果,从而优化时间复杂度,是经典的用空间替换时间的做法。
本质前缀和与差分是⼀对互逆的运算

二、一维差分

2.1 差分数组构建方式

根据定义f[i]=a[i]−a[i−1]
根据差分数组的性质f[i] += a[i], f[i+1] −= a[i]

2.2 根据差分数组的性质处理区间修改

核心公式f[L] + = c, f[R+1] − = c

2.3 还原数组

对差分数组做⼀次「前缀和」,就可以还原出原数组

三、一维差分经典算法题

3.1【模板】差分

3.1.1题目

链接:【模板】差分

3.1.2 算法原理

依照刚才讲解一维差分原理模拟即可

3.1.3代码

3.1.3.1 根据差分数组的性质

c 复制代码
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int n, m;
int f[N];
int main()
{
	cin >> n >> m;

	for (int i = 1; i <= n; i++)
	{
		int x;
		cin >> x;

		f[i] += x;
		f[i + 1] -= x;
	}
	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;
}

3.1.3.2 根据定义

c 复制代码
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int n, m;
int f[N];
int a[N];
int main()
{
	cin >> n >> m;

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

	for (int i = 1; i <= n; i++)
		f[i] = a[i] - a[i - 1];
	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;
}

3.2 海底高铁

3.2.1题目

链接:海底高铁

3.2.2 算法原理

1.先考虑如何让花费最小,想要求最小花费,需要知道每⼀段高铁被「乘坐了多少次」,记作f[i],那么最小花费就是「买票的花费」与「买卡的花费」两者之间的最小值:f[i]

(1)买票花费:;a[i]×f[i]

(2)买卡花费,乘车花费+工本费:b[i]×f[i]+c[i]

(3)那么最小花费就是:mincost=min(a[i]×f[i], b[i]×f[i]+c[i])

2.接下来考虑如何求出每⼀段⾼铁被「乘坐了多少次」。根据访问城市的序列p1 ,p2 ,p3 ,...,pm 可知,对于任意⼀次访问 pi∼p ,我们会乘坐[pi ~ pi + 1 - 1]之间所有的高铁,比如p =i 3, pi+1 = 6,那么[3,5]之间所有的高铁都会被乘坐⼀次,相当于每个数都加上1,「注意6位置不会乘坐到」。那么我们就可以利用「差分数组」

(1)创建⼀个全为0的差分数组;

(2)遍历访问序列,对于每⼀次访问f[p]+ i +, f[p]− i+1 −

(3)然后对差分数组做⼀次前缀和,就得到每个⾼铁乘坐的次数

注意城市访问的序列有可能pi > pi + 1,此时应该「交换」⼀下顺序

3.2.3代码

c 复制代码
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
typedef long long LL;
LL f[N];

int main()
{
	LL n, m;
	cin >> n >> m;

	LL x;
	cin >> x;
	for (int i = 2; i <= m; i++)
	{
		LL y;
		cin >> y;

		// x -> y
		if (y > x)
		{
			f[x]++;
			f[y]--;
		}

		// y -> x
		else
		{
			f[x]--;
			f[y]++;
		}
		x = y;
	}

	for (int i = 1; i < n; i++)
		f[i] += f[i - 1];

	LL ret = 0;
	for (int i = 1; i < n; i++)
	{
		LL a, b, c;
		cin >> a >> b >> c;
		ret += min(a * f[i], c + b * f[i]);
	}

	cout << ret << endl;
	return 0;

}

总结与每日励志

摘要: 本文介绍了差分算法的基本原理及其应用,重点讲解了一维差分的构建方式、区间修改处理及数组还原方法。通过经典算法题如【模板】差分和海底高铁问题,展示了差分在优化时间复杂度中的实际应用。文章还提供了详细的代码实现,帮助读者快速掌握差分算法。最后以励志语句"永远相信美好的事情即将发生"鼓励读者坚持学习与成长。 关键词: 差分算法、前缀和、区间修改、时间复杂度、算法实战

相关推荐
小白程序员成长日记1 小时前
2025.12.07 力扣每日一题
算法·leetcode·职场和发展
不悔哥1 小时前
路由器特性——网络状态检测
linux·c语言·网络·tcp/ip·智能路由器
tangjunjun-owen2 小时前
OpenCV在Visual Studio中的完整配置教程
人工智能·opencv·visual studio
TeleostNaCl2 小时前
使用 Android Jetpack 中的 Startup 组件快速实现组件初始化逻辑与主模块解耦
android·经验分享·android jetpack·androidx·android runtime·jetpack android
小李小李快乐不已2 小时前
图论理论基础(5)
数据结构·c++·算法·机器学习·动态规划·图论
承渊政道2 小时前
C++学习之旅【C++基础知识介绍】
c语言·c++·学习·程序人生
民乐团扒谱机2 小时前
【微实验】大规模网络的社区检测Clauset–Newman–Moore聚类算法(附完整MATLAB代码)
算法·matlab·聚类·聚类算法·cnm·语义
烛衔溟2 小时前
C语言图论:有向图基础
c语言·数据结构·图论·有向图
枫叶丹42 小时前
【Qt开发】Qt窗口(七) -> QColorDialog 颜色对话框
c语言·开发语言·c++·qt