C++ 一维前缀和

C++ 一维前缀和

    1. 什么是前缀和
    1. 前缀和算法有什么好处?

1、前缀和

前缀和是指某序列的前n项和,可以把它理解为数学上的数列的前n项和,而差分可以看成前缀和的逆运算。合理的使用前缀和与差分,可以将某些复杂的问题简单化。

2.前缀和算法有什么好处?

先来了解这样一个问题:

输入一个长度为n的整数序列。接下来再输入m个询问,每个询问输入一对l, r。对于每个询问,输出原序列中从第l个数到第r个数的和。

我们很容易想出暴力解法,遍历区间求和。

代码如下:


> const int N = 1e5 + 10; 
> int a[N]; 
> int n,m; 
> scanf("%d%d", &n, &m);
> for(int i = 1; i <= n; i++) scanf("%d", &a[i]); while(m--) {
>     int l, r;
>     int sum = 0;
>     scanf("%d%d", &l, &r);
>     for(int i = l; i <= r; i++)
>     { 
>         sum += a[i];
>     }
>     printf("%d\n",sum); }



这样的时间复杂度为O(n * m),如果n和m的数据量稍微大一点就有可能超时,而我们如果使用前缀和的方法来做的话就能够将时间复杂度降到O(n + m),大大提高了运算效率。

具体做法:
!](https://i-blog.csdnimg.cn/direct/b80bb120095b41eaa84f38d7a1e315cc.png)

对于每次查询,在这里插入图片描述
为什么不是a[ r ]-a[ l ]?_

在这里插入图片描述

问:最上面的代码不是用a[ i ] 来存累加的和吗 这里怎么又变成sum了?

答:都可以 用a[i]存就不用再定义sum数组,分不清的情况那就定义两个数组,a数组用来存1-n , sum数组存前缀和。

### C++ 中实现二维前缀和算法C++ 中,可以通过构建一个 `prefixSum` 数组来存储二维数组的前缀和。以下是基于给定引用中的方法以及常见实践的一个完整示例。 #### 构建二维前缀和的核心逻辑 对于一个大小为 \(N \times M\) 的二维数组 `nums`,可以定义一个新的二维数组 `prefixSum` 来保存每一位置上的前缀和。核心公式如下: \[ \text{prefixSum}[i][j] = \text{nums}[i][j] + \text{prefixSum}[i-1][j] + \text{prefixSum}[i][j-1] - \text{prefixSum}[i-1][j-1] \] 其中需要注意边界条件处理,当索引越界时对应的值应视为 0[^3]。 下面是完整的代码实现: ```cpp #include <iostream> #include <vector> using namespace std; // 计算二维前缀和函数 void calculatePrefixSum(const vector<vector<int>>& nums, vector<vector<int>>& prefixSum) { int n = nums.size(); if (n == 0) return; int m = nums[0].size(); // 初始化 prefixSum 数组 prefixSum.assign(n, vector<int>(m, 0)); for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { // 边界条件判断 int top = (i > 0) ? prefixSum[i - 1][j] : 0; int left = (j > 0) ? prefixSum[i][j - 1] : 0; int topLeft = (i > 0 && j > 0) ? prefixSum[i - 1][j - 1] : 0; // 更新当前格子的前缀和 prefixSum[i][j] = nums[i][j] + top + left - topLeft; } } } int main() { // 输入样例数据 vector<vector<int>> nums = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; vector<vector<int>> prefixSum; calculatePrefixSum(nums, prefixSum); // 输出结果 cout << "二维前缀和矩阵:" << endl; for (const auto& row : prefixSum) { for (const auto& val : row) { cout << val << "\t"; } cout << endl; } return 0; } ``` #### 关键点解析 1. **初始化**:创建与输入数组相同尺寸的 `prefixSum` 数组并将其初始值设为零。 2. **动态规划更新规则**:通过累加当前位置上方、左方的前缀和减去重叠部分(即左上角),从而得到新的前缀和值[^2]。 3. **时间复杂度分析**:该算法仅需一次遍历整个二维数组即可完成计算,因此总体的时间复杂度仍保持为 O(N * M)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值