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

算法——前缀和算法

1. 什么是前缀和算法

前缀和算法(Prefix Sum)是一种用于快速计算数组元素之和的技术。它通过预先计算数组中每个位置前所有元素的累加和,将这些部分和存储在一个新的数组中,从而在需要计算某个区间的和时,可以通过简单的减法操作得到结果,而不必重新遍历整个区间。

2. 一维前缀和

在这里我们通过一个例题来讲解:【模板】前缀和_牛客题霸_牛客网 (nowcoder.com)

题目描述如下

我们在一个数组中想要q次访问一段下标为 [l, r] 的数据和即

我们稍加分析可以发现,如果我们使用暴力解法(将区间内所有数字相加)时间复杂度为O(q*N),在这里我们可以使用前缀和的算法,来使每次访问的时间复杂度降低到O(1),在这里我们要提前预备好一个dp数组,dp[i]表示从下标1开始到下标i的数值和,dp[i] = dp[i-1] + arr[i],这样填完dp表后,[l, r]的数值和sum = dp[r] - dp[l-1],此外在这里有一个细节需要我们注意:下标为什么是从1开始的?——假如要计算[0, 2]的话,我们需要使用dp[2] - dp[-1],这样就会带来不便。

我们可以得到这道题的代码

#include <iostream>
#include <vector>
using namespace std;

int main() 
{
    int n = 0, q = 0;
    cin >> n >> q;
    vector<int> arr(n + 1);
    for (int i = 1; i <= n; i++) cin >> arr[i];

    // 使用long long 避免整型溢出
    vector<long long> dp(n + 1);
    for (int i = 1; i <= n; i++) dp[i] = dp[i-1] + arr[i];

    int l = 0, r = 0;
    while (q--)
    {
        cin >> l >> r;
        cout << dp[r] - dp[l-1] << endl;
    }

    return 0;
}

3. 二维前缀和

在这里我们使用另一个例题:【模板】二维前缀和_牛客题霸_牛客网 (nowcoder.com)

在这里,我们需要得到从下标(x1, y1)->(x2, y2)所有数值和,我们同样可以使用前缀和来解决。二维的前缀和与一维的相似,我们可以规定dp[i][j]表示从下标(1, 1)->(i, j)所有数值和,我们要计算的dp[i][j]可以按如下方式计算

即dp[i][j] = dp[i-1][j] + dp[i][j-1] + arr[i][j] - dp[i-1][j-1],在预备好了dp数组过后,我们如何来使用它呢?图解如下

我们可以使用如下代码解决此问题

#include <iostream>
#include <vector>
using namespace std;

int main() 
{
    int n = 0, m = 0, q = 0;
    cin >> n >> m >> q;
    vector<vector<int>> arr(n + 1, vector<int>(m + 1));
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin >> arr[i][j];

    vector<vector<long long>> dp(n + 1, vector<long long>(m + 1));
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            dp[i][j] = dp[i-1][j] + dp[i][j-1] + arr[i][j] - dp[i-1][j-1];

    int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
    while (q--)
    {
        cin >> x1 >> y1 >> x2 >> y2;
        cout << dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] + dp[x1-1][y1-1] << endl;
    }

    return 0;
}

http://www.kler.cn/a/230906.html

相关文章:

  • <设计模式>单例模式懒汉和饿汉
  • ​​​​​​​CleanMyMac X有什么优势?到底好不好用?
  • Linux下库函数、静态库与动态库
  • 1Panel面板如何安装并结合内网穿透实现远程访问本地管理界面
  • Python编程:17个提升工作效率的自动化脚本
  • 物流|基于Springboot的物流管理系统设计与实现(源码+数据库+文档)
  • docker 入门教程之概述
  • 位运算:进制
  • dolphinscheduler海豚调度(一)简介快速体验
  • 基于51 单片机的交通灯系统 源码+仿真+ppt
  • 改变AI服务器:探索界面互连芯片技术的创新突破
  • yolov8使用旋转框自己做数据集检测
  • python 多趟算法举例
  • MySQL:从基础到实践(简单操作实例)
  • MySQL学习记录——사 表结构的操作
  • C++俄罗斯方块 -- 菜单展示和选择 -- 方法
  • 前端代码评审规范
  • 关于自动驾驶概念的学习和一些理解
  • docker 入门教程
  • 假期作业 2月6号