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

news2024/9/27 7:21:12

一.简介

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

具体而言,对于一个长度为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)修改数据

 

因为要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)查询

 


 五.模板题

(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]的值,若小于所给的教室,就说明这以范围的订单有问题

(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;
}

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

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

相关文章

【Rust笔记】意译解构 Object Safety for trait

意译解构Object Safety for trait 借助【虚表vtable】对被调用成员函数【运行时内存寻址】的作法允许系统编程语言Rust模仿出OOP高级计算机语言才具备的【专用多态Ad-hoc Polymorphism】特性。 计算机高级语言中的“多态”术语是一个泛指。它通常可被细化为 基于继承关系的“子…

时间复杂度介绍及其计算

时间复杂度 1.算法效率 如何衡量一个算法的好坏呢&#xff1f;看这段代码&#xff1a; long long Fib(int N) {if(N < 3)return 1;return Fib(N-1) Fib(N-2); }这是斐波那契数列的递归代码&#xff0c;非常简洁&#xff0c;那么这就一定说明它好吗&#xff1f;答案显而易…

智能家居是否可与ChatGPT深度融合?

​ ChatGPT自2022年面世以来&#xff0c;已为亿万网民提供智能问答服务。然而我们是否曾想到&#xff0c;这一人工智能驱动的聊天机器人&#xff0c;是否可为智能家居赋能? 要实现ChatGPT与智能家居设备之间的无缝对话&#xff0c;单单依靠一台终端是远远不够的。ChatGPT必须…

Java基础_多线程

Java基础_多线程 什么是多线程并发, 并行多线程的实现方式继承Thread类实现Runnable接口实现Callable接口和Future接口实现方式对比 常见的成员方法常见方法进程的优先级守护线程礼让线程插入线程 线程安全线程的生命周期售票模拟同步代码块同步方法lock锁 死锁 生产者和消费者…

【C语言】通讯录1.0 (静态版)

前言 通讯录是一种记录联系人信息的工具&#xff0c;包括姓名、电话号码、电子邮件地址、住址等。 此通讯录是基于自定义类型的基础上进行制作&#xff0c;通讯录&#xff08;静态版&#xff09;&#xff0c;后期会进行通讯录的更新 ****** 有需要源代码&#xff0c;见文章末尾…

大于号在python中怎么打,python大于等于怎么写

大家好&#xff0c;小编为大家解答python中大于并小于一个数代码的问题。很多人还不知道python中大于等于且小于等于&#xff0c;现在让我们一起来看看吧&#xff01; 1、python 中不等于怎么表示 #!/usr/bin/python a1 b2 if ab: print "a 等于 b" if a!b: print &…

ArcGIS Pro 制作一张立体地形图

在各位关掉文章之前,先把成果贴上来 下面开始操作步骤贴图,这个真的很简单,没有什么复杂的软件联动和操作 这是哥斯达黎加部分区域的30mDEM,数据链接我放在最后。 首先,找到工具【栅格函数】—【统计分析】,选择下载好的栅格,领域设置行列数都改为6,点击创建新图层。然…

从官网认识 JDK,JRE,JVM 三者的关系

点击下方关注我&#xff0c;然后右上角点击...“设为星标”&#xff0c;就能第一时间收到更新推送啦~~~ JVM 是一些大厂面试必问点&#xff0c;要想解决 OOM、性能调优方面的问题&#xff0c;掌握 JVM 知识必不可少&#xff0c;从今天开始&#xff0c;将为大家介绍 JVM 的常用知…

ShardingSphere Pipeline 兼容 MySQL 时间类型 解读

背景 ShardingSphere 在日常中&#xff0c;开发者经常会用到时间类型&#xff0c;如果熟悉的时间类型涉及到了时区、精度&#xff0c;哪种时间类型更合适&#xff1f;JDBC 驱动中又有哪些注意事项&#xff1f;因此&#xff0c;对数据库时间类型有更深入的了解&#xff0c;有助于…

android framework车载桌面CarLauncher的TaskView详细源码分析

1、构建相关的TaskView&#xff0c;装载到对应的ViewGroup b站免费视频教程讲解&#xff1a; https://www.bilibili.com/video/BV1wj411o7A9/ //packages/apps/Car/Launcher/src/com/android/car/carlauncher/CarLauncher.java void onCreate() { //ignoresetContentView(R.…

管理类联考——写作——记忆篇——论证有效性分析——析错口诀

析错口诀 概念不明确&#xff0c;我就说它概念模糊&#xff0c;并做不利它的解释。【有概念模糊之嫌&#xff0c;A是理解1&#xff1f;还是理解2&#xff1f;】概念有变换&#xff0c;我就说它混淆概念&#xff0c;并指出混淆的环节。&#xff08;概念推概念&#xff0c;我就看…

类方法(成员方法)与构造方法的区别与联系

&#xff08;粗略理解为&#xff1a;除了构造方法以外的所有方法都是成员方法&#xff09; 区别&#xff1a; 构造方法在创建对象时用new调用&#xff0c;是为了给对象的数据进行初始化&#xff0c;没有返回值。 成员方法是实现对类中成员变量的操作&#xff0c;提供某些功能…

【图论】kruskal算法

一.介绍 Kruskal&#xff08;克鲁斯卡尔&#xff09;算法是一种用于解决最小生成树问题的贪心算法。最小生成树是指在一个连通无向图中&#xff0c;选择一棵包含所有顶点且边权重之和最小的树。 下面是Kruskal算法的基本步骤&#xff1a; 将图中的所有边按照权重从小到大进行…

JUC并发工具类

一、ReentrantLock 特点&#xff1a;独占、可重入、公平/非公平、可中断、支持多个条件变量 1、常用api ReentrantLock实现了Lock接口&#xff0c;Lock类规范定义了如下方法 lock()&#xff1a;获取锁&#xff0c;调用该方法的线程会获取锁&#xff0c;当锁获得后&#xff0…

想做上位机,学C#还是QT?

学习C#还是Qt&#xff0c;取决于你的具体需求和偏好。 如果你计划开发跨平台的桌面应用程序&#xff0c;并且希望使用一种更轻量级、直观的界面框架&#xff0c;那么Qt可能是一个不错的选择。Qt是一个功能丰富且成熟的跨平台框架&#xff0c;支持多种开发语言&#xff08;包括…

第J2周:ResNet50V2算法实战与解析

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章&#xff1a;365天深度学习训练营-第J2周&#xff1a;ResNet50V2算法实战与解析&#x1f356; 原作者&#xff1a;K同学啊|接辅导、项目定制 目录 一、论文解读1. ResNetV2结构与…

【需求响应】一种新的需求响应机制DR-VCG研究

目录 1 主要内容 2 部分代码 3 程序结果 4 程序链接 1 主要内容 该程序对应文章《Contract Design for Energy Demand Response》&#xff0c;电力系统需求响应&#xff08;DR&#xff09;用来调节用户对电能的需求&#xff0c;即在预测的需求高于电能供应时&#xff0c;希…

VS Code调试Darknet

一、安装插件 二、连接服务器 三、调试darknet工程 {"version": "2.0.0","options": {"cwd": "${workspaceFolder}"},"tasks": [{"label": "clean","type": "shell",&qu…

数据结构之动态顺序表(附带完整程序)

&#x1f388;基本概念 &#x1f308;一.线性表、顺序表的定义 ☀️&#xff08;1&#xff09;线性表&#xff1a; 是n个具有相同特性的数据元素的有限序列。线性表在逻辑上是线性结构&#xff0c;但在物理上存储时&#xff0c;通常以数组和链式结构的形式存储。 ☀️&…

C# 关于使用newlife包将webapi接口寄宿于一个控制台程序、winform程序、wpf程序运行

C# 关于使用newlife包将webapi接口寄宿于一个控制台程序、winform程序、wpf程序运行 安装newlife包 Program的Main()函数源码 using ConsoleApp3; using NewLife.Log;var server new NewLife.Http.HttpServer {Port 8080,Log XTrace.Log,SessionLog XTrace.Log }; serv…