C++前缀和神技:区间问题瞬杀模板

目录

🔥 前缀和核心价值

🌟 一维前缀和模板

1. 预处理公式

2. 代码实现

3. 动态图示

📦 二维前缀和模板

1. 预处理公式

2. 代码实现

3. 二维示意图

🚨 六大避坑指南

💡 复杂度分析

🌈 LeetCode实战


🔥 前缀和核心价值

暴力法的痛点

// 计算区间和,时间复杂度O(n)  
int sum = 0;  
for(int i=l; i<=r; i++) sum += arr[i]; 

前缀和优势:将区间查询复杂度从 O(n) 降为 O(1),处理海量数据时性能炸裂!


🌟 一维前缀和模板

1. 预处理公式
prefix[i] = prefix[i-1] + arr[i]  
区间和公式:sum(l, r) = prefix[r] - prefix[l-1]  
2. 代码实现
vector<int> arr = {3, 1, 4, 2, 5};  
int n = arr.size();  

// 前缀和数组(从1开始存储)  
vector<int> prefix(n+1, 0);  
for(int i=1; i<=n; i++) {  
    prefix[i] = prefix[i-1] + arr[i-1]; // arr索引注意-1  
}  

// 查询区间[2,4]的和(对应原数组索引1~3)  
int l=2, r=4;  
int sum = prefix[r] - prefix[l-1]; // 4+2+5=11  
3. 动态图示
原数组索引:0  1  2  3  4  
原数组值: 3  1  4  2  5  
前缀和数组:0  3  4  8 10 15  

查询[2,4] → prefix[4] - prefix[1] = 10 - 3 = 7 ❌  
正确对应:原数组索引1~3 → 前缀和[2,4] → 10 - 3 = 7  
(注意索引转换的细节!)  

📦 二维前缀和模板

1. 预处理公式
prefix[i][j] = prefix[i-1][j] + prefix[i][j-1] - prefix[i-1][j-1] + matrix[i-1][j-1]  
区间和公式:sum(x1,y1,x2,y2) = prefix[x2][y2] - prefix[x1-1][y2] - prefix[x2][y1-1] + prefix[x1-1][y1-1]  
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>> prefix(m+1, vector<int>(n+1, 0));  
for(int i=1; i<=m; i++){  
    for(int j=1; j<=n; j++){  
        prefix[i][j] = prefix[i-1][j] + prefix[i][j-1] - prefix[i-1][j-1] + matrix[i-1][j-1];  
    }  
}  

// 查询子矩阵和 (x1,y1)=(2,2) 到 (x2,y2)=(3,3)  
int sum = prefix[3][3] - prefix[1][3] - prefix[3][1] + prefix[1][1];  
// 对应原矩阵的右下角4个元素:5+6+8+9=28  
3. 二维示意图
原矩阵:  
1 2 3  
4 5 6  
7 8 9  

前缀和矩阵(带虚拟边界):  
0  0  0  0  
0  1  3  6  
0  5 12 21  
0 12 27 45  

查询(2,2)-(3,3)区域:  
prefix[3][3] - prefix[1][3] - prefix[3][1] + prefix[1][1]  
=45 - 6 - 12 + 1 = 28  

🚨 六大避坑指南

  1. 索引偏移陷阱:前缀和数组通常从1开始,原数组从0开始

  2. 初始化边界prefix[0] = 0

  3. 整数溢出:用long long存储前缀和

  4. 二维减法的容斥原理:注意加减顺序

  5. 空区间处理:当l>r时应返回0

  6. 负数处理:哈希表统计时需考虑负前缀和


💡 复杂度分析

操作一维二维
预处理O(n)O(mn)
单次查询O(1)O(1)
空间复杂度O(n)O(mn)

🌈 LeetCode实战

  1. 303. 区域和检索 - 数组不可变(一维模板题)

  2. 304. 二维区域和检索 - 矩阵不可变(二维模板题)

  3. 560. 和为K的子数组(哈希表+前缀和经典)

  4. 1248. 统计「优美子数组」(奇偶性转换技巧)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值