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

一.简介

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

具体而言,对于一个长度为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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux NDK交叉编译rtmp 与 ffmpeg+rtmp交叉编译(v7a,v8a) 完成流程

最近在学RTMP,记录一下完成的编译流程 我是mac 电脑,但是mac上编译一直通过不了,后来才换到服务器上编译, 其实mac也能编译,只是最开始踩到坑里面了… 这里记录一下linux编译完整流程 环境: NDK: android-ndk-r17cFfmpeg: ffmpeg4.2.2 (高版本也可以编译)system: mac 1. …

云原生架构

1. 何为云原生&#xff1f; 很多IT业内小伙伴会经常听到这个名词&#xff0c;那么什么是云原生呢&#xff1f;云原生是在云计算环境中构建、部署和管理现代应用程序的软件方法。 当今时代&#xff0c;众多企业希望构建高度可扩展、灵活且有弹性的应用程序&#xff0c;以便能够快…

数据链路层是如何传递数据的

数据链路层是如何传递数据的 数据链路层功能概述封装成帧透明传输差错控制 数据链路层功能概述 数据链路层的主要作用就是加强物理层传输原始比特流的功能。其负责将物理层提供的可能出错的物理连接&#xff0c;改造成逻辑上无差错的数据链路。 数据链路层包括三个基本问题&a…

Matlab的SimuLink对FS32K144编程--SPI通讯控制12bitDAC输出

​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ 1、硬件介绍&#xff0c;DAC芯片&#xff1a;AD5328BRUZ DAC_SPI_SCK----PTD0(SPI1) DAC_SPI_DIN----PTE0(SPI1)单片…

【Vuvuzela 声音去噪算法】基于流行的频谱减法技术的声音去噪算法研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

[BSidesCF 2020]Had a bad day1

进入环境&#xff0c;一上来就是一段激励的话&#xff0c;没有啥特别的&#xff0c;源码中也没有看见啥有用的提示 但主要是有&#xff0c;参数的传递&#xff0c;加上前面的index.php&#xff0c;想到了PHP伪协议&#xff0c;或许我们可以直接查看一下隐藏源码 报错了&#xf…

【Linux进程】进程控制(下) {进程程序替换:程序替换的工作原理,程序替换函数exec*,简单的命令行解释器}

四、进程程序替换 之前用fork创建子进程后&#xff0c;父子进程执行同一个程序的不同代码段。 如何使子进程执行另一个不同的程序呢&#xff1f;子进程需要进行程序替换&#xff01; 程序替换&#xff0c;就是通过特定的接口&#xff0c;将磁盘上一个全新的程序&#xff08;包…

OBS 迁移--华为云

一、创建迁移i任务 1. 登录管理控制台。 2. 单击管理控制台左上角的 在下拉框中选择区域。 3. 单击“ 服务列表 ”&#xff0c;选择“ 迁移 > 对象存储迁移服务 OMS ”&#xff0c;进入“ 对象存储迁移服务 ”页面。 4. 单击页面右上角“ 创建迁移任务 ”。 5. 仔细阅读…

Verilog语法学习——LV4_移位运算与乘法

LV4_移位运算与乘法 题目来源于牛客网 [牛客网在线编程_Verilog篇_Verilog快速入门 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page1&tabVerilog篇&topicId301) 题目 题目描述&#xff1a; 已知d为一个8位数&#xff0c;请在每个时钟周期分别输出该数乘1/…

Python爬取IP归属地信息及各个地区天气信息

一、实现样式 二、核心点 1、语言&#xff1a;Python、HTML&#xff0c;CSS 2、python web框架 Flask 3、三方库&#xff1a;requests、xpath 4、爬取网站&#xff1a;https://ip138.com/ 5、文档结构 三、代码 ipquery.py import requests from lxml import etree # 请求…

了解Unity编辑器之组件篇Miscellaneous(九)

一、Aim Constraint&#xff1a;是一种动画约束&#xff0c;用于使一个对象朝向另一个对象或一个指定的矢量方向 Activate按钮&#xff1a;用于激活或停用Aim Constraint。当Aim Constraint处于激活状态时&#xff0c;其约束效果将应用于目标对象。 Zero按钮&#xff1a;用于将…

Spring Boot单元测试入门指南

Spring Boot单元测试入门指南 JUnit是一个成熟和广泛应用的Java单元测试框架&#xff0c;它提供了丰富的功能和灵活的扩展机制&#xff0c;可以帮助开发人员编写高质量的单元测试。通过JUnit&#xff0c;开发人员可以更加自信地进行重构、维护和改进代码&#xff0c;同时提高代…

Skin Shader 使用自动生成的Thickness

Unity2023.2的版本&#xff0c;Thickness 自动化生成&#xff0c;今天测试了一把&#xff0c;确实不错。 1.Render 设置 在Project Settings->Graphics->HDRP Global Settings中 Frame Setting->Rendering->Compute Thickness 打开 2.Layer设置 2.1添加Layer&…

如何提高自己的软件测试水平之bug定位

同学们在面试投简历的时候会经常看到人家公司JD上写的要求之一&#xff0c;如下&#xff1a; 这句话大家不要以为随便写写的&#xff0c;在我工作的十几年过程中起码见过10个以上试用期没过的公司新人&#xff0c;公司在衡量一个测试工程师是否专业的标准之一就是&#xff1a;…

Kotlin基础(八):泛型

前言 本文主要讲解kotlin泛型&#xff0c;主要包括泛型基础&#xff0c;类型变异&#xff0c;类型投射&#xff0c;星号投射&#xff0c;泛型函数&#xff0c;泛型约束&#xff0c;泛型在Android中的使用。 Kotlin文章列表 Kotlin文章列表: 点击此处跳转查看 目录 1.1 泛型基…

opencv-28 自适应阈值处理-cv2.adaptiveThreshold()

什么是自适应阈值处理? 对于色彩均衡的图像&#xff0c;直接使用一个阈值就能完成对图像的阈值化处理。但是&#xff0c;有时图像的色彩是不均衡的&#xff0c;此时如果只使用一个阈值&#xff0c;就无法得到清晰有效的阈值分割结果图像。 有一种改进的阈值处理技术&#xff…

Mybatis-Plus学习笔记,包含mybatis-plus基本使用,各种插件使用等等

&#x1f600;&#x1f600;&#x1f600;创作不易&#xff0c;各位看官点赞收藏. 文章目录 Mybatis-Plus笔记1、简介2、Mybatis-Plus Demo 程序3、Mybatis-Plus 常见注解4、Mybatis-Plus 条件构造器 Wrapper5、Mybatis-Plus 插件5.1、乐观锁插件5.2、分页插件5.3、逻辑删除插件…

OJ练习第145题——并行课程 III

力扣链接&#xff1a;2050. 并行课程 III 题目描述 给你一个整数 n &#xff0c;表示有 n 节课&#xff0c;课程编号从 1 到 n 。同时给你一个二维整数数组 relations &#xff0c;其中 relations[j] [prevCoursej, nextCoursej] &#xff0c;表示课程 prevCoursej 必须在课…

Python(四十七)列表对象的创建

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

脚手架(vue-cli)的安装详细教程

首先要下载node.js 下载 | Node.js 中文网 (nodejs.cn)https://nodejs.cn/download/ 大家根据自己的系统来选择哪个&#xff0c;我是Windows系统&#xff0c;所以选择红色箭头所指的安装包去安装&#xff01;&#xff01;&#xff01; 接下来双击安装&#xff01;&#xff01;…