【数学】差分数组(一维差分)

这篇具有很好参考价值的文章主要介绍了【数学】差分数组(一维差分)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一.简介

【数学】差分数组(一维差分),数学专栏,算法,c++

 差分数组是指对一个一维数组进行差分操作得到的新数组。差分操作是指计算原数组中相邻元素之间的差异,并将这些差异作为新数组的元素。

具体而言,对于一个长度为n的一维数组x,其差分数组diff的第i个元素可以通过以下公式计算得到:

diff[i] = x[i] - x[i-1]

其中,diff[0] = x[0],因为第一个元素没有前一个元素。

差分数组的长度比原数组少1,因为差分操作会减少一个元素。差分数组中的元素表示了原数组中相邻元素之间的差异。

需要注意的是,差分数组可以通过反向操作(即累加)来恢复原始数组。这意味着,如果有原始数组的差分数组,可以通过对差分数组进行累加操作来还原原始数组。

 


二.差分数组的优势

当我们遇到对一个数组的一系列范围的数据反复修改时,我们可以用差分数组。但值得注意的是查询次数要少,修改次数要多,这样效果更明显


三.差分数组与前缀和的区别

(1)前缀和是通过sum[i]=sum[i-1]+a[i]所实现的。它可以预处理后O(1)的速度查询区间之和。但在区间和要修改,则需要树状数组等数据结构实现。

(2)差分数组是通过d[i]=a[i]-a[i-1]所实现。它可以预处理后O(1)的速度修改区间数组的数值,但在查询时要O(n)。


四.详细分析差分数组

(1)修改数据

【数学】差分数组(一维差分),数学专栏,算法,c++

 

因为要a[1]+1,则a[1]又比a[0]多了1,则d[1]+1即可。

又因为a[1]+1,a[2]+1,所以d[2]=a[2]-a[1]并不变

最后a[3]+1,d[4]=a[4]-a[3],所以d[4]应当-1;

总结:

若 [ i , j ]+1,则 d[i]+1,d[j+1]-1;

若[ i , j ]-1,则 d[i]-1,d[j+1]+1;


(2)查询

【数学】差分数组(一维差分),数学专栏,算法,c++

 


 五.模板题

(1)题目

1.题目描述:给一个数组a,经过m次修改,输出数组a

2.输入:第一行有n,m,表示数组a有n个元素,经过m次修改

              第二行n个数,表示n个元素

              第i(【3,3+m】)行,每行有三个数:l,r,s表示数组下标从l到r,分别加s

3.输出:修改后的数组a

4.样例输入

5 3
1 2 3 4 5
1 3 1
1 5 1
3 4 2

5.样例输出:3 4 7 7 6

6.数据范围:1<=n,m<1e5;

(2)参考代码 

#include<bits/stdc++.h>
#define maxn 100005
using namespace std;
inline int read(){
	int ans=0,f=1;
	char cc=getchar();
	while(cc<'0' || cc>'9'){
		if(cc=='-') f=-1;
		cc=getchar();
	}
	while(cc>='0' && cc<='9'){
		ans=(ans<<1)+(ans<<3)+(cc-'0');
		cc=getchar();
	}
	return ans*f;
}
int a[maxn],d[maxn];
int n,m;
int main(){
	cin>>n>>m;
	//O(n)
	for(int i=1;i<=n;i++) a[i]=read();
	//预处理
	for(int i=1;i<=n;i++) d[i]=a[i]-a[i-1]; 
	//O(m)
	while(m--){
		int l=read(),r=read(),s=read();
		d[l]+=s ;d[r+1]-=s;
	}
	int sum=0;
	for(int i=1;i<=n;i++){
	//	调试 
	//	cout<<d[i]<<" ";
		sum+=d[i];
		cout<<sum<<" ";
	}
	return 0;
}

六.应用

(1)题目

P1083 [NOIP2012 提高组] 借教室 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

(2)思路 

可以用二分答案实现,二分订单,再找到大范围,最后到小范围;使用差分数组,加快了修改数据的速度,再sum累计,算出a[i]的值,若小于所给的教室,就说明这以范围的订单有问题文章来源地址https://www.toymoban.com/news/detail-614168.html

(3)参考代码(O(nlogm))

#include<bits/stdc++.h>
#define maxn 1000005
using namespace std;
inline int read(){
	int ans=0,f=1;
	char cc=getchar();
	while(cc<'0' || cc>'9'){
		if(cc=='-') f=-1;
		cc=getchar();
	}
	while(cc>='0' && cc<='9'){
		ans=(ans<<1)+(ans<<3)+(cc-'0');
		cc=getchar();
	}
	return ans*f;
}
int n,m;  //天,订单
int a[maxn]; //每天有的教室
int s[maxn],e[maxn],t[maxn]; //第i的订单的起,末,量 
long long d[maxn]; //差分数组 
bool f(int x){
	memset(d,0,sizeof(d));
	for(int i=1;i<=x;i++){
		d[s[i]]+=t[i]; d[e[i]+1]-=t[i];
	} 
	long long sum=0; //第i天需要的教室
	for(int i=1;i<=n;i++){
		sum+=d[i];
		if(sum>a[i]) return 1;
	}
	return 0;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) a[i]=read();
	for(int i=1;i<=m;i++){
		t[i]=read();s[i]=read();e[i]=read();
	} 
	int l=1,r=m;
	//二分答案找订单 
	int ans=0;
	if(f(m)==0){
		cout<<0;return 0;
	}
	//O(nlogm) 
	while(l<=r){
		int mid=(l+r)/2;
		if(f(mid)){
			ans=mid;
			r=mid-1;
		}else{
			l=mid+1;
		}
	}
	cout<<-1<<endl<<ans<<endl;
	return 0;
}

到了这里,关于【数学】差分数组(一维差分)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构与算法—一维数组、二维数组、矩阵、顺序串、链接串的C++代码实现

    1、一维数组:ArrayOneD.h 数组这种数据结构可以看作线性表的推广。数组一般采用顺序存储的方法表示。 这是一个模板类 ArrayOneD 的实现,用于表示一维数组。它包括了 构造函数、拷贝构造函数、析构函数、重载下标运算符、重载赋值运算符、求数组长度、重新设置数组长度

    2024年02月07日
    浏览(45)
  • 【算法】【差分数组】解决连续空间改变相同值的问题

    将原数组每个值减去前一个值,得到的新数组是差分数组 d i s [ k ] = a [ k ] − a [ k − 1 ] dis[k] = a[k] - a[k-1] d i s [ k ] = a [ k ] − a [ k − 1 ] 如: 原数组为 [ 1 , 2 , 3 , 5 ] [1,2,3,5] [ 1 , 2 , 3 , 5 ] 得到的差分数组为 [ 1 , 1 , 1 , 2 ] [1,1,1,2] [ 1 , 1 , 1 , 2 ] 通过计算差分数组的前缀和,可以得

    2024年02月08日
    浏览(69)
  • 差分(一维)

    本篇文章介绍前缀和的逆运算,差分。 什么是差分? 差分是前缀和的逆运算,比如 (a[n]) 是原数组, (s[n]) 是 (a[n]) 的前缀和数组,那么对于 (s[n]) 来说, (a[n]) 就是 (s[n]) 的差分数组。 假设原数组为 (a[n]) , (b[n]) 为差分数组,那么他们之间的关系为: b[1] = a[1] ,

    2024年02月08日
    浏览(25)
  • 有限差分法-一维热传导方程及其Matlab程序实现

    2.2.2 一维热传导方程 热传导方程是描述热量在介质中传导的数学模型。在许多实际应用中,我们需要预测物体的温度随时间和空间的演化情况,这就需要用到热传导方程。 热传导方程的背景可以追溯到18世纪,当时科学家们对热的本质和热量如何传递产生了浓厚的兴趣。傅里

    2024年02月10日
    浏览(30)
  • 用Matlab求解一维非稳态导热问题(有限差分法+显式离散)

    章熙民的第六版《传热学》里,较为简单的介绍了非稳态导热的数值计算,本文根据此书,以计算一个可视为无限大平壁的复合墙体传热过程为例,讨论一维非稳态导热问题数值求解的问题。 这里把参考书目的PDF分享出来,希望可以帮助到大家学习传热学,里面有章熙民的第

    2023年04月22日
    浏览(33)
  • Java——一维数组和二维数组(主要详讲一维数组)

    目录 一维数组 创建,初始化,赋值 注意 一些数组的便捷使用方法 使用 .length得到数组长度 Arrays相关的使用 二维数组 文章某些地方会出现java与c语言的比较 文章内容参考韩顺平老师的课堂笔记 可以先创建再初始化,也可以创建的时候直接初始化。但是,如果选择先创建再

    2024年02月01日
    浏览(36)
  • 【动态规划】【数学】【C++算法】805 数组的均值分割

    视频算法专题 动态规划汇总 数学 给定你一个整数数组 nums 我们要将 nums 数组中的每个元素移动到 A 数组 或者 B 数组中,使得 A 数组和 B 数组不为空,并且 average(A) == average(B) 。 如果可以完成则返回true , 否则返回 false 。 注意:对于数组 arr , average(arr) 是 arr 的所有元素的和

    2024年02月20日
    浏览(34)
  • 【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值

    《博主简介》 小伙伴们好,我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌ 更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍 感谢小伙伴 们点赞、关注! class   Solution :      def   mySqrt ( self ,  x :   int )   -   int :       

    2024年02月04日
    浏览(53)
  • 5.一维数组与字符数组

    数组:指一组具有相同数据类型的数据的有序集合。 一维数组的定义格式为 类型说明符 数组名[常量表达式]; 常量表达式中可以包含常量和符号常量,但不能包含变量 可以只给一部分元素赋值,如int a[10]={0,1,2,3,4};后面的值会默认为0 在对全部数组元素赋初值时,由于数据的

    2024年02月12日
    浏览(34)
  • 【PHP】二维数组转一维数组

    在 PHP 中,如果你想将一个二维数组转换为一维数组,你可以使用几种不同的方法。以下是一些常见的方法: array_column() 用于提取数组中的列,最为直接 array_map() 用于对数组中的每个元素应用回调函数,返回的是由回调函数的返回值组成的新数组。 以上任何一种方法都可以

    2024年02月04日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包