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

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

目录

🔥 差分核心价值

🌟 一维差分模板

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. 用邮票贴满网格(二维差分经典)

相关文章:

  • SpringBoot实现发邮件功能+邮件内容带模版
  • 理解大模型的function call ,思维链COT和MCP 协议
  • H-ZERO自定义全局字体 支持项目个性化字体需求
  • 【WRF-Urban】城市冠层/建筑楼层设置
  • C++ 学习笔记(三)—— 入门+类和对象
  • MySQL 8主从复制配置最佳实践
  • uniapp 实现微信小程序电影选座功能
  • leetcode-50.Pow(x,n)
  • 火山云对比阿里云的优势在哪里
  • 【Linux操作系统——学习笔记二】Linux简单导航命令操作
  • 安徽建筑安全员A证考试的报名条件是什么?
  • spring boot 过滤器简单demo
  • Java实现字符串大写字母转小写的多种方法及优化策略
  • Web Component 教程(三):生命周期方法的触发时机与实际应用
  • 【C++】树和二叉树的实现(下)
  • 数据库:一文掌握 MongoDB 的各种指令(MongoDB指令备忘)
  • uniapp常用组件
  • 在 Vue.js 中使用递归组件:轻松处理嵌套数据结构
  • Python 爬虫(2)Web请求
  • 第六章-PHP错误处理
  • 习近平会见塞尔维亚总统武契奇
  • 明星同款撕拉片,为何能炒到三四百一张?
  • 上海推动AI+文旅深度融合,MaaS平台和产业基地落地徐汇
  • 汪明荃,今生不负你
  • 家庭相册㉙在沪打拼25年,我理解了父母清晨去卖蜜饯的辛苦
  • 扶桑谈|素称清廉的石破茂被曝受贿,日本政坛或掀起倒阁浪潮