当前位置: 首页 > news >正文

算法学习日记 | 差分

🧠 算法学习日记 | 今天我用「差分」解了两道题,原来“懒惰更新”能这么优雅!

大家好,我是你们的算法学习搭子 👋
今天继续我的算法入门之旅,重点练习了**差分(Difference Array)**这一高效的数据结构技巧。

很多人觉得“差分”只是用来做区间加法的工具,但其实,它是一种延迟处理思想的体现。
我们不直接修改每个元素,而是记录“变化点”,最后再一次性还原整个数组。

今天我完整做了两道题,每一道都坚持用最朴素的差分逻辑实现。下面我把题目原文我的原始代码原封不动贴出来,不做任何删减或美化,只为真实记录学习过程。


🔹 题目一:区间更新

问题描述
给定一个长度为 $ n $ 的数组 $ a[1], a[2], \ldots, a[n] $。同时给定 $ m $ 个操作,每个操作有三个整形数据 $ x, y, z $。每个操作的意义就是给数组中下标为 $ x $ 与下标为 $ y $ 之间(包括 $ x, y $)的元素的值加上 $ z $。

输入格式
输入有多组数据,数据组数不大于 5。每一组数据第一行有两个整数 $ n, m (0 < n, m < 10^5) $。第二行有 $ n $ 个整数,分别代表 $ a[1], a[2], \ldots, a[n] (0 \leq a[i] < 10) $ 的初始值。接下来就 $ m $ 行,每一行有 3 个整数 $ x, y, z (0 < x \leq y \leq n, 0 < z < 10) $。

输出格式
在一行内输出这个序列的所有元素的值,并且每个值之间应该以空格隔开。

输入样例

10 5 0 0 0 0 0 0 0 0 0 0 1 5 1 2 6 1 3 7 1 4 9 1 5 10 1 1 1 1 1 2

输出样例

1 2 3 4 5 4 3 2 2 1 3

运行限制

  • 语言:C++
  • 最大运行时间:2s
  • 最大运行内存:1024M

✅ 我的代码(完全保留原始写法)

#include<iostream>usingnamespacestd;constintN=1e5+3;inta[N],d[N];voidsolve(intn,intm){for(inti=1;i<=n;++i)cin>>a[i];for(inti=1;i<=n;++i)d[i]=a[i]-a[i-1];while(m--){intx,y,z;cin>>x>>y>>z;d[x]+=z,d[y+1]-=z;}for(inti=1;i<=n;++i){a[i]=a[i-1]+d[i];}for(inti=1;i<=n;++i){cout<<a[i]<<" ";}}intmain(){intn,m;while(cin>>n>>m){solve(n,m);cout<<endl;}return0;}

🔹 题目二:小明的彩灯

题目描述
小明拥有 $ N $ 个彩灯,第 $ i $ 个彩灯的初始亮度为 $ a_i $。

小明将进行 $ Q $ 次操作,每次操作可选择一段区间,并使区间内彩灯的亮度 $ +x((x $ 可能为负数)。

求 $ Q $ 次操作后每个彩灯的亮度(若彩灯亮度为负数则输出 0)。

输入描述
第一行包含两个正整数 $ N, Q $,分别表示彩灯的数量和操作的次数。
第二行包含 $ N $ 个整数,表示彩灯的初始亮度。
接下来 $ Q $ 每行包含一个操作,格式如下:
l r x,表示将区间 $ l \sim r $ 的彩灯的亮度 $ +x $。

约束:$ 1 \leq N, Q \leq 5 \times 10^5,,0 \leq a_i \leq 10^9,,1 \leq l \leq r \leq N,,-10^9 \leq x \leq 10^9 $。

输出描述
输出共 1 行,包含 $ N $ 个整数,表示每个彩灯的亮度。

输入输出样例

输入 5 3 2 2 1 5 1 3 3 4 5 5 1 1 -100
输出 0 5 6 10 10

✅ 我的代码(完全保留原始写法)

#include<iostream>usingnamespacestd;constintN=5e5+5;longlonga[N],d[N];voidsolve(intn,intq){for(inti=1;i<=n;++i)cin>>a[i];for(inti=1;i<=n;++i)d[i]=a[i]-a[i-1];for(inti=0;i<q;++i){intl,r;longlongx;cin>>l>>r>>x;d[l]+=x,d[r+1]-=x;}for(inti=1;i<=n;++i){a[i]=a[i-1]+d[i];}for(inti=1;i<=n;++i){if(a[i]<0)a[i]=0;cout<<a[i]<<" ";}}intmain(){intn,q;cin>>n>>q;solve(n,q);return0;}

🌟 我的思考

这两道题虽然看起来不同,但都用了差分的核心思想

  • 区间更新:每次操作只在d[x] += zd[y+1] -= z处做标记,避免逐个修改。
  • 小明的彩灯:同理,先建差分数组,再批量还原,最后判断是否为负。

你会发现:

差分的本质是“懒惰更新”—— 不立即改变所有元素,而是记录“变化起点”和“变化终点”。

这种思想在大数据场景中特别有用。比如:

  • 有 100 万个灯泡,要执行 1 万次区间加法 → 用暴力会超时,用差分只需 $ O(n + m) $

而且,差分可以扩展到二维、多维,甚至用于解决“区间最小值”、“区间最大值”等问题(结合线段树)。


✅ 总结

  • 差分的核心是:记录变化点,延迟还原
  • 适用于多次区间加减操作的问题
  • 时间复杂度:每次操作 $ O(1) $,最后还原 $ O(n) $
  • 关键在于构建差分数组:d[i] = a[i] - a[i-1]
  • 还原方式:a[i] = a[i-1] + d[i]
  • 注意边界:d[y+1] -= z,防止越界

http://www.jsqmd.com/news/374804/

相关文章:

  • 多云失控预警:终端风险激增下的破局之道
  • 2026年全国二手设备回收厂家权威榜单 助力各类场景资源高效再生 覆盖多业态适配与资源循环 - 深度智识库
  • 【毕业设计】基于springboot的小学阶段图形化编程竞赛辅导网站设计与实现(源码+文档+远程调试,全bao定制等)
  • 基于深度学习的行为预测:从LSTM到GNN与Transformer,如何更好地编码场景上下文?
  • 闲置沃尔玛超市购物卡别愁!3种实测有效回收方法,轻松变现不浪费 - 京回收小程序
  • FFMpeg全解析:从“万能媒体转换器”到工程化音视频管线的底层逻辑 - 教程
  • Facebook推出AI功能:可为头像和动态添加动画效果
  • 众测
  • 荷兰数据保护局遭遇Ivanti零日攻击后主动报告数据泄露
  • 2026年最新版腾讯手游助手下载与使用详解:从安装配置到性能优化的完整方案 - PC修复电脑医生
  • 基于深度学习的混合波束成形的Matlab实现
  • 【计算机毕业设计案例】基于springboot的小学阶段图形化编程竞赛辅导网站设计与实现(程序+文档+讲解+定制)
  • Java毕设项目推荐-基于springboot的停车场收费车辆进出管理系统设计与实现【附源码+文档,调试定制服务】
  • Complyance获2000万美元A轮融资,AI智能体助企业合规
  • Java毕设选题推荐: 基于Spring Boot的智能停车场管理系统设计与实现基于springboot的停车场收费管理系统设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 人形机器人公司Apptronik融资9.35亿美元估值超50亿
  • 【课程设计/毕业设计】基于springboot的小学阶段图形化编程竞赛辅导网站设计与实现【附源码、数据库、万字文档】
  • 【计算机毕业设计案例】基于springboot的停车场收费管理系统设计与实现 Spring Boot框架下的停车场自动化收费与管理系统(程序+文档+讲解+定制)
  • 如何修复iPhone短信消失问题?
  • 计算机毕业设计之springboot仿汉堡王自助点餐系统
  • 自动泊车技术-入门理解
  • 计算机毕业设计之ssm网上选课微信小程序的设计与实现
  • 如何从 iPhone 仅传输喜爱的照片?
  • 必看!2026年服装企业管理系统ERP软件推荐排行榜,解锁高效运营新选择
  • 如何在没有iTunes的情况下重启/恢复出厂设置iPhone
  • 【课程设计/毕业设计】基于springboot的停车场收费管理系统设计与实现车辆管理、停车位、收费【附源码、数据库、万字文档】
  • 单片机串行DA转换器系统研究与设计
  • 2026年口碑好的AI手机:三星定义AI手机的下一程
  • Nodejs+vue+ElementUI框架饮品仓库管理系统的设计与实现
  • 带有语音播报的指纹密码锁控制系统设计