【算法】差分思想:强大的算法技巧

news2024/11/13 9:36:36

📢博客主页:https://blog.csdn.net/2301_779549673
📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📢本文由 JohnKi 原创,首发于 CSDN🙉
📢未来很长,值得我们全力奔赴更美好的生活✨

在这里插入图片描述

在这里插入图片描述

文章目录

  • 📢前言
  • 🏳️‍🌈一、差分思想概述
  • 🏳️‍🌈二、差分思想的优缺点
  • 🏳️‍🌈例题题解
  • 👥总结


📢前言

大家可以先看一下题目
在这里插入图片描述

在这里插入图片描述
由于随着订单数量的增加,每天可用教室的数量一定单调下降。
因此我们可以二分出最后一天没出现负值的订单编号。

剩下的问题是如何快速求出经过若干订单后,每天所剩的教室数量。
每个订单的操作是 [Li,Ri]全部减去 di

因此我们可以用差分来加速处理过程。


🏳️‍🌈一、差分思想概述

在 C++ 中,差分思想主要涉及差分数组和原数组的关系。差分数组也是一个数组,定义为 d [ i ] = a r r [ i ] − a r r [ i − 1 ] ( i ! = 0 ) d[i] = arr[i] -arr[i-1](i != 0) d[i]=arr[i]arr[i1](i!=0),且 d [ i ] = 0 d[i] = 0 d[i]=0,其中 arr[] 即为原数组。例如,有原数组 :9 3 5 2 7,对应的差分数组 :9 -6 2 -3 5。可以看出,差分数组的第一个值等于原数组第一个值,而其他位置的值等于原数组对应位置的值减去前一个位置的值

差分数组的精髓在于可以通过其前缀和得到原数组。假设差分数组为 b ,原数组为 a ,那么 a [ i ] = b [ i ] + a [ i − 1 ] a[i] = b[i] + a[i-1] a[i]=b[i]+a[i1] 比如,若 i=1 ,那 a[1] = b[0] + b[1]
i=2 ,那 a[2] = b[0] + b[1] +b[2]

通过这种关系,可以利用差分数组在 O(1)时间复杂度内将区间内的元素都加上某个数。例如输入一个长度为 n 的整数序列,有频繁区间修改操作时,如让第 1 个数到第 1000 万个数每个数都加上 1,如果采用暴力方法遍历区间,时间复杂度是 O(n) ,效率非常低。

而使用差分数组,只需要对差分数组中的两个位置进行修改即可实现区间修改,大大降低了时间复杂度O(1)。比如,在区间 [l,r] 上所有的数值都加上常数 c ,只需要将 b[l] = b[l] + c ,然后在 b[r+1] = b[r+1] - c ,这样就把一连串的循环遍历修改 转变为了对两个位置数字的修改 ,效率大大提升。

🏳️‍🌈二、差分思想的优缺点

差分思想在多个方面展现出显著的优势。

首先,在简化运算方面,差分数组能够将对区间元素的复杂操作转化为对差分数组中特定位置的简单修改。例如,当需要给一个区间 [l,r] 上的数组加一个常数 c 时,传统方法需要依次遍历区间内的每个元素进行加法操作,时间复杂度为 O(n) 。而利用差分数组,只需对差分数组中的两个位置进行修改,即 b[l] = b[l] + cb[r+1] = b[r+1] - c ,时间复杂度降低至 O(1) 。这种简洁高效的操作方式在处理大规模数据和频繁的区间修改操作时优势尤为明显。

其次,在提高效率方面,对于包含大量区间修改操作的场景,C++ 差分思想能够极大地提高程序的执行效率。以处理长度为 n=100000 的整数序列为例,假设有 m=1000 个操作,每个操作都是对一个区间进行修改。如果使用传统方法,每次操作都需要遍历区间内的元素,总的时间复杂度将高达 O(m * n) 。而采用差分数组,每次操作只需要对两个位置进行修改,总的时间复杂度降低为 O(m + n) 。通过对比可以看出,差分数组在处理大量区间修改操作时效率提升巨大。

然而,差分思想也并非完美无缺。

虽然使用差分思想优化了区间的修改效率,使其变成了一个常数级的操作,但对原数组的访问效率却受到了一定的影响。因为对原数组中某个元素的访问需要通过差分数组的前缀和来计算,时间复杂度变为了 O(i) 。例如,当需要获取原数组中第 i 个元素的值时,需要计算差分数组中前 i 项的和,这在一定程度上增加了访问原数组的时间成本。

综上所述,C++ 差分思想在简化运算和提高效率方面具有明显优势,但在访问原数组时也存在一定的局限性。在实际应用中,需要根据具体情况权衡利弊,选择合适的方法来处理数据。

🏳️‍🌈例题题解

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<iostream>
#include<cstring>

using namespace std;

typedef long long LL;
const int N = 1000001;

int n, m;
int r[N];
int d[N], s[N], t[N];
LL e[N];

bool check(int mid)
{
	memset(e, 0, sizeof(e));

	for (int i = 1; i <= mid; i++)
	{
		e[s[i]] += d[i];
		e[t[i] + 1] -= d[i];
	}
	for (int i = 1; i <= n; i++)
	{
		e[i] += e[i - 1];
		if (e[i] > r[i])
			return false;
	}
	return true;
}

int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &r[i]);
	}
	for (int i = 1; i <= m; i++)
	{
		scanf("%d%d%d", &d[i], &s[i], &t[i]);
	}
	int L = 0, R = m;
	while (L < R)
	{
		int mid = L + (R - L + 1) / 2;
		if (check(mid))
			L = mid;
		else
			R = mid -1;
	}
	if (R == m)
		printf("%d", 0);
	else
		printf("%d\n%d", -1, R + 1);
}



👥总结


本篇博文对 差分思想 做了一个较为详细的介绍,不知道对你有没有帮助呢

觉得博主写得还不错的三连支持下吧!会继续努力的~

请添加图片描述

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

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

相关文章

Linux(CentOS8)服务器安装RabbitMQ

我安装了很久都没有成功, 各种问题, 每次的异常都不一样, 现将成功安装过程做个总结 安装前工作 确保已经安装了一些基础工具和组件库 下载安装包 https://www.erlang.org/patches/otp-24.3.4.5 https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.9.15/ra…

Python热频随机森林分类器算法模型模拟

&#x1f3af;要点 研究发射测量斜率和时滞热频率表征&#xff0c;使用外推法计算三维磁场并定性比较使用基于焓的热演化环模型模拟每条线的热力学响应&#xff0c;测试低频、中频和高频热场景使用光学薄、高温、低密度等离子体的单位体积辐射功率或发射率公式等建模计算使用直…

GPU加速生物信息分析的尝试

GPU工具分类 实话实说&#xff0c;暂时只有英伟达的GPU才能实现比较方便的基因组分析集成化解决方案&#xff0c;其他卡还需要努力呀&#xff0c;或者需要商业公司或学术团体的努力开发呀&#xff01;FPGA等这种专用卡的解决方案也是有的&#xff0c;比如某测序仪厂家&#xf…

基于stm32使用ucgui+GUIBuilder开发ui实例

1 项目需求 1.1 基于Tft 触摸屏实现一个自锁按键 1.2 按键在按下后背景色需要进行变化&#xff0c;以凸显当前按键状态&#xff08;选中or 未选中&#xff09; 1.3 按键选中时对某一gpio输出低电平&#xff0c;非选中时输出高电平 2 移植 ucgui UCGUI的文件数量很大&#x…

happens-before

happens-before 一、happens-before 规则的含义 happens-before 是 Java 内存模型&#xff08;JMM&#xff09;中用于定义多线程之间操作顺序的规则集合。它规定了如果一个操作 A happens-before 另一个操作 B&#xff0c;那么 A 的结果对 B 可见&#xff0c;并且在 B 执行之…

未来最好的程序开发语言:Rust - 安装rust

安装 Rust - Rust 程序设计语言一门帮助每个人构建可靠且高效软件的语言。https://www.rust-lang.org/zh-CN/tools/install 设置下载源:

开源 AI 智能名片链动 2+1 模式 S2B2C 商城小程序与社交电商的崛起

摘要&#xff1a;本文深入探讨了社交电商迅速发展壮大的原因&#xff0c;并分析了开源 AI 智能名片链动 21 模式 S2B2C 商城小程序在社交电商中的重要作用。通过对传统电商与社交电商的对比&#xff0c;以及对各发展因素的剖析&#xff0c;阐述了该小程序如何为社交电商提供新的…

【机器学习】6 ——最大熵模型

机器学习6——最大熵模型 目录 机器学习6——最大熵模型最大熵&#xff08;maximum entropy&#xff09;模型模型模型学习&#xff08;估计参数&#xff09;模型评价应用 最大熵&#xff08;maximum entropy&#xff09;模型 选择熵最大的概率模型 熵是衡量不确定性的&#xf…

7 递归——206. 反转链表 ★

7 递归 206. 反转链表 给你单链表的头节点head,请你反转链表,并返回反转后的链表。 示例 1: 输入:head = [1,2,3,4,5] 输出:[5,4,3,2,1] 算法设计 可以充分利用原有的存储空间,通过修改指针实现单链表的就地逆置。相当于将所有的箭头反向,头指针指向原链表的尾部。…

苏州科技大学、和数联合获得国家知识产权局颁发的3项发明专利证书

近日&#xff0c;基于“苏州科技大学-和数智能软件区块链技术工程实验室”的研究成果&#xff0c;国家知识产权局正式授权了苏州科技大学、苏州和数区块链应用研究院联合申报的3项发明专利证书。 分别为&#xff1a; 一种基于双账本的物联网数据存储与共享方法 一种面向物联网…

SpringBoot框架之KOB项目 - 配置Mysql与注册登录模块(上)

框架模型 每一个客户端&#xff08;client&#xff09;都会和后端&#xff08;SpringBoot&#xff09;进行通信&#xff0c;例如如果一个用户进行登录&#xff0c;需要向后端发送username、password&#xff0c;SpringBoot可以理解为一个一直在跑的程序&#xff0c;不断对用户…

使用HTML和CSS制作网页的全面指南

目录 引言 一、理解HTML 1. 什么是HTML&#xff1f; 2. HTML文档的基本结构 3. 常用的HTML标签 4. 示例&#xff1a;创建一个简单的HTML页面 二、理解CSS 1. 什么是CSS&#xff1f; 2. CSS的使用方式 3. CSS选择器和属性 4. 常用的CSS属性 三、创建网页的步骤 1. 规…

蓝桥杯-基于STM32G432RBT6的LCD进阶(LCD界面切换以及高亮显示界面)

目录 一、页面切换内容详解 1.逻辑解释 2.代码详解 code.c&#xff08;内含详细讲解&#xff09; code.h main.c 3.效果图片展示 ​编辑 二、页面选项高亮内容详解 1.逻辑解释 2.读入数据 FIRST.第一种高亮类型 code.c&#xff08;内含代码详解&#xff09; code.…

说一说Zookeeper的应用场景及其原理

一 ZooKeeper简介 ZooKeeper是一个分布式的&#xff0c;开放源码的分布式应用程序协调服务&#xff0c;是Google的Chubby一个开源的实现&#xff0c;是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件&#xff0c;提供的功能包括&#xff1a;配置维护、域名…

【C++】深入理解引用:从基础到进阶详解

&#x1f984;个人主页:小米里的大麦-CSDN博客 &#x1f38f;所属专栏:C_小米里的大麦的博客-CSDN博客 &#x1f381;代码托管:C: 探索C编程精髓&#xff0c;打造高效代码仓库 (gitee.com) ⚙️操作环境:Visual Studio 2022 目录 一、前言 二、引用的概念 三、常引用&#x…

c++249多态

#include<iostream> using namespace std; class Parent { public:Parent(int a){this->a a;cout << " Parent" << a << endl;} public:virtual void print()//在子类里面可写可不写 {cout << "Parent" <<a<&l…

虚拟机centos_7 配置教程(镜像源、配置centos、静态ip地址、Finalshell远程操控使用)

文章目录 一、下载镜像源&#xff08;准备工作&#xff09;1、开源网站2、下载 二、VMware配置centos三、配置静态IP地址四、Finalshell使用1、下载Finalshell2、连接虚拟机 五、谢谢观看&#xff01; 一、下载镜像源&#xff08;准备工作&#xff09; 1、开源网站 有许多开源…

[Linux]:进程间通信(下)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;Linux学习 贝蒂的主页&#xff1a;Betty’s blog 1. system V通信 前面我们所探究的通信方式都是基于管道文件的&#xff0c;而…

day22JS-npm中的部分插件使用方法

1. 静态资源目录 静态资源目录就是访问服务器的某些路劲时候&#xff0c;服务器可以吐出一个写好的指定页面。 实现思路&#xff1a; 1、先判断要找的路径是否是文件&#xff0c;如果是文件&#xff0c;就加载发给对方。 2、如果是文件夹&#xff0c;找到这个文件夹所在路径中…

STL相关简介

string 看到这个词&#xff0c;相信大家一定都很好奇什么是string&#xff0c;它有什么作用呢&#xff1f;今天&#xff0c;就让我们一起来了解一下关于string的简介吧~ 目录 string 1. 什么是STL 2. STL的版本 3. STL的六大组件 4. STL的重要性 5. 如何学习STL 6.STL的…