C++差分风暴:区间修改终极模板

ops/2025/3/19 7:26:23/

目录

🔥 差分核心价值

🌟 一维差分模板

1. 核心思想

2. 代码实现

3. 动态图示

📦 二维差分模板

1. 核心公式

2. 代码实现

3. 二维修改示意图

🚨 六大避坑指南

💡 复杂度对比

🌈 LeetCode实战


🔥 差分核心价值

暴力法的痛点

// 区间[l,r]增加val,时间复杂度O(n)  
for(int i=l; i<=r; i++) arr[i] += val; 

差分优势:将区间修改复杂度从 O(n) 降为 O(1),批量操作性能飙升!


🌟 一维差分模板

1. 核心思想
  • 差分数组diff[i] = arr[i] - arr[i-1]

  • 区间修改diff[l] += valdiff[r+1] -= val

  • 还原数组:前缀和计算

2. 代码实现
vector<int> arr = {3,1,4,2,5};  
int n = arr.size();  // 构建差分数组  
vector<int> diff(n+2, 0); // 多开空间防越界  
for(int i=1; i<=n; i++){  diff[i] = arr[i-1] - (i==1 ? 0 : arr[i-2]);  
}  // 区间[2,4](索引1~3)加10  
int l=2, r=4, val=10;  
diff[l] += val;  
diff[r+1] -= val;  // 还原数组  
vector<int> new_arr(n);  
new_arr[0] = diff[1];  
for(int i=1; i<n; i++){  new_arr[i] = new_arr[i-1] + diff[i+1];  
}  
// 结果:3,11,14,12,5  
3. 动态图示
原数组:  3   1   4   2   5  
差分数组:3  -2   3  -2   3  操作:区间[2-4]加10  
差分变化:  
diff[2] +=10 → -2+10=8  
diff[5] -=10 → 3-10=-7  新差分数组:3  8   3  -2  -7  
还原后数组:  
3 → 3+8=11 → 11+3=14 → 14-2=12 → 12-7=5  

📦 二维差分模板

1. 核心公式
给子矩阵(x1,y1)-(x2,y2)加val:  
diff[x1][y1] += val  
diff[x1][y2+1] -= val  
diff[x2+1][y1] -= val  
diff[x2+1][y2+1] += val  
2. 代码实现
vector<vector<int>> matrix = {{1,2,3}, {4,5,6}, {7,8,9}};  
int m = matrix.size(), n = matrix[0].size();  // 初始化二维差分  
vector<vector<int>> diff(m+2, vector<int>(n+2, 0));  
for(int i=1; i<=m; i++){  for(int j=1; j<=n; j++){  diff[i][j] += matrix[i-1][j-1];  diff[i][j+1] -= matrix[i-1][j-1];  }  
}  // 子矩阵(1,1)-(2,2)加5(原矩阵行0-1,列0-1)  
int x1=1, y1=1, x2=2, y2=2, val=5;  
diff[x1][y1] += val;  
diff[x1][y2+1] -= val;  
diff[x2+1][y1] -= val;  
diff[x2+1][y2+1] += val;  // 还原矩阵  
vector<vector<int>> res(m, vector<int>(n));  
for(int i=0; i<m; i++){  int row_sum = 0;  for(int j=0; j<n; j++){  row_sum += diff[i+1][j+1];  res[i][j] = row_sum;  }  
}  
// 结果:  
// 6  7  3  
// 9 10 6  
// 7  8 9  
3. 二维修改示意图
原矩阵:  
1 2 3  
4 5 6  
7 8 9  差分影响范围:  
+5          -5  ↓           ↓  
(1,1)     (1,3)  5  -5  -5  5  最终矩阵:  
(1+5)=6  (2+5)=7 3  
(4+5)=9 (5+5+5)=15 6  
7        8       9  

🚨 六大避坑指南

  1. 索引偏移陷阱:原数组从0开始,差分数组从1开始

  2. 越界防护:差分数组多开两格空间

  3. 还原顺序:二维需先计算行前缀和,再列方向累积

  4. 负数处理:差分数组允许负数存在

  5. 多操作叠加:支持连续多次修改后统一还原

  6. 初始值处理:原数组全0时差分数组也全0


💡 复杂度对比

操作暴力法差分法
区间修改O(n)O(1)
单次查询O(1)O(n)
初始化O(1)O(n)
适合场景查多改少改多查少

🌈 LeetCode实战

  1. 1109. 航班预订统计(一维差分模板题)

  2. 1094. 拼车(差分+上下车模型)

  3. 798. 得分最高的最小轮调(差分+区间覆盖)

  4. 2132. 用邮票贴满网格(二维差分经典)


http://www.ppmy.cn/ops/166975.html

相关文章

验证哥德巴赫猜想(C语言)

哥德巴赫猜想&#xff1a;任一大于2的偶数都可写成两个质数之和。&#xff08;——欧拉提出的观点&#xff09; 代码如下&#xff1a; #include<stdio.h> #include<stdbool.h> #include<math.h> bool isprime(int n) { if (n < 2) return f…

机器学习驱动的智能化电池管理技术与应用

电池管理技术概述 电池的工作原理与关键性能指标 电池管理系统的核心功能 SOC估计 SOH估计 寿命预测 故障诊断 人工智能机器学习 基础 人工智能的发展 机器学习的关键概念 机器学习在电池管理中的应用案例介绍 人工智能在电池荷电状态估计中的应用 荷电状态估计…

启幕数据结构算法雅航新章,穿梭C++梦幻领域的探索之旅——二叉树序列构造探秘——堆的奥义与实现诗篇

人无完人&#xff0c;持之以恒&#xff0c;方能见真我&#xff01;&#xff01;&#xff01; 共同进步&#xff01;&#xff01; 文章目录 一、堆的定义与结构二、堆的实现1.堆的初始化和销毁堆的初始化堆的销毁 2.向上调整算法和入堆向上调整算法入堆 3.向下调整算法和出堆顶数…

centos6.10 编译gcc11.5.0 支持mutilib(32bit,64bit)glibc2.11.3

我希望制作一个gcc&#xff0c;使用自带低版本glibc&#xff08;2.11.3&#xff09;系统自带glibc是2.12&#xff0c;同时要支持编译32位和64位代码&#xff0c;这样制作的gcc拷贝到其他高版本glibc系统&#xff0c;也可以生成兼容性好的代码 export SRC/dd/gcc-src export BUI…

【算法】动态规划

⭐️个人主页&#xff1a;小羊 ⭐️所属专栏&#xff1a;Linux 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 动态规划总结1、常见动态规划Fibonacci数列杨辉三角最小花费爬楼梯孩子们的游戏不同路径不同路径II珠宝的最高价值下降路径最小和…

leetcode 3110. 字符串的分数 简单

给你一个字符串 s 。一个字符串的 分数 定义为相邻字符 ASCII 码差值绝对值的和。 请你返回 s 的 分数 。 示例 1&#xff1a; 输入&#xff1a;s "hello" 输出&#xff1a;13 解释&#xff1a; s 中字符的 ASCII 码分别为&#xff1a;h 104 &#xff0c;e …

SY6280AAC usb电流限流电子开关

电流设置图 电路原理图 参考链接 SY6280AAC -PDF数据手册-参考资料-立创商城https://item.szlcsc.com/datasheet/SY6280AAC/56162.html?spmsc.it.xds.a&lcsc_vidRgVaBABUQgdeAQZTR1FbUwBfRlEIVFNTEVlXXgFSTlAxVlNSRVNXVFBRRVZWVDsOAxUeFF5JWAIASQYPGQZABAsLWA%3D%3D 我做…

C++学习之云盘项目nginx

1.复习 2.知识点概述 1. 一些基本概念 1.1 Nginx 初步认识 1.2 正向 / 反向代理 1.3 域名和 IP 2. Nginx 安装和配置 2.1 安装 2.2 配置 3. Nginx 的使用 3.1 部署静态网页 3.2 反向代理和负载均衡 课外知识导读 1. URL 和 URI 2. DNS 解析过程 1. 一些基…