一维二维前缀和、差分,c++

前缀和(Prefix Sum)是一种常用的预处理技术,用于快速计算数组中任意区间的和。前缀和的核心思想是通过预处理,将区间和的查询时间复杂度从 (O(n)) 降低到 (O(1))。

以下是前缀和的模板和示例:


1. 一维前缀和

1.1 模板

#include <iostream>
#include <vector>

// 计算前缀和
std::vector<int> computePrefixSum(const std::vector<int>& nums) {
    int n = nums.size();
    std::vector<int> prefix(n + 1, 0); // prefix[0] = 0

    for (int i = 1; i <= n; i++) {
        prefix[i] = prefix[i - 1] + nums[i - 1];
    }

    return prefix;
}

// 查询区间和
int queryRangeSum(const std::vector<int>& prefix, int l, int r) {
    return prefix[r + 1] - prefix[l];
}

int main() {
    std::vector<int> nums = {1, 2, 3, 4, 5};

    // 计算前缀和
    std::vector<int> prefix = computePrefixSum(nums);

    // 查询区间和
    int sum1 = queryRangeSum(prefix, 1, 3); // 2 + 3 + 4 = 9
    int sum2 = queryRangeSum(prefix, 0, 4); // 1 + 2 + 3 + 4 + 5 = 15

    std::cout << "Sum of [1, 3]: " << sum1 << std::endl;
    std::cout << "Sum of [0, 4]: " << sum2 << std::endl;

    return 0;
}

输出:

Sum of [1, 3]: 9
Sum of [0, 4]: 15

1.2 应用场景

  • 区间和查询:快速计算任意区间的和。
  • 差分数组:结合差分数组,可以高效处理区间更新操作。

2. 二维前缀和

2.1 模板

#include <iostream>
#include <vector>

// 计算二维前缀和
std::vector<std::vector<int>> compute2DPrefixSum(const std::vector<std::vector<int>>& matrix) {
    int rows = matrix.size();
    int cols = matrix[0].size();

    std::vector<std::vector<int>> prefix(rows + 1, std::vector<int>(cols + 1, 0));

    for (int i = 1; i <= rows; i++) {
        for (int j = 1; j <= cols; j++) {
            prefix[i][j] = prefix[i - 1][j] + prefix[i][j - 1] - prefix[i - 1][j - 1] + matrix[i - 1][j - 1];
        }
    }

    return prefix;
}

// 查询子矩阵和
int querySubmatrixSum(const std::vector<std::vector<int>>& prefix, int x1, int y1, int x2, int y2) {
    return prefix[x2 + 1][y2 + 1] - prefix[x1][y2 + 1] - prefix[x2 + 1][y1] + prefix[x1][y1];
}

int main() {
    std::vector<std::vector<int>> matrix = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    // 计算二维前缀和
    auto prefix = compute2DPrefixSum(matrix);

    // 查询子矩阵和
    int sum1 = querySubmatrixSum(prefix, 0, 0, 1, 1); // 1 + 2 + 4 + 5 = 12
    int sum2 = querySubmatrixSum(prefix, 1, 1, 2, 2); // 5 + 6 + 8 + 9 = 28

    std::cout << "Sum of submatrix [0,0] to [1,1]: " << sum1 << std::endl;
    std::cout << "Sum of submatrix [1,1] to [2,2]: " << sum2 << std::endl;

    return 0;
}

输出:

Sum of submatrix [0,0] to [1,1]: 12
Sum of submatrix [1,1] to [2,2]: 28

2.2 应用场景

  • 子矩阵和查询:快速计算任意子矩阵的和。
  • 图像处理:用于计算图像中某个区域的总和或平均值。

3. 前缀和与差分数组的结合

3.1 差分数组模板

差分数组是前缀和的逆操作,用于高效处理区间更新。

#include <iostream>
#include <vector>

// 区间更新
void rangeUpdate(std::vector<int>& diff, int l, int r, int val) {
    diff[l] += val;
    if (r + 1 < diff.size()) {
        diff[r + 1] -= val;
    }
}

// 获取最终数组
std::vector<int> getFinalArray(const std::vector<int>& diff) {
    std::vector<int> result(diff.size() - 1, 0);
    result[0] = diff[0];
    for (int i = 1; i < result.size(); i++) {
        result[i] = result[i - 1] + diff[i];
    }
    return result;
}

int main() {
    std::vector<int> nums = {1, 2, 3, 4, 5};
    std::vector<int> diff(nums.size() + 1, 0);

    // 区间更新
    rangeUpdate(diff, 1, 3, 10); // 对 [1, 3] 区间加 10

    // 获取最终数组
    auto result = getFinalArray(diff);

    // 输出结果
    std::cout << "Final Array: ";
    for (int num : result) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出:

Final Array: 1 12 13 14 5 

3.2 应用场景

  • 区间更新:对数组的某个区间进行统一加减操作。
  • 多次更新后查询:在多次区间更新后,快速获取最终数组。

4. 总结

  • 一维前缀和:用于快速计算一维数组的区间和。
  • 二维前缀和:用于快速计算二维矩阵的子矩阵和。
  • 差分数组:用于高效处理区间更新操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/962643.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于Spring Security 6的OAuth2 系列之八 - 授权服务器--Spring Authrization Server的基本原理

之所以想写这一系列&#xff0c;是因为之前工作过程中使用Spring Security OAuth2搭建了网关和授权服务器&#xff0c;但当时基于spring-boot 2.3.x&#xff0c;其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0&#xff0c;结果一看Spring Security也升级…

STC32通用GPIO中断,库函数配置方式 AI8051U和STC32G已测试没有问题

近来STC的单片机已经出到32位了&#xff0c;并且个人自己打板测试了几个型号&#xff0c;相比之前的51完全不是一个量级&#xff0c;可以通过以下这张图片中的信息来感受一下如今的32位8051单片机的强大&#xff0c;也是很很期待25年的这一新作了&#xff01; 配图为AI8052U或…

Git进阶之旅:Git Hub注册创建仓库

介绍&#xff1a; GitHub 是一个面向开源及私有软件项目的托管平台&#xff0c;因为只支持 git 作为唯一的版本库格式进行托管&#xff0c;故名 GitHub 仓库注册&#xff1a; GitHub官网&#xff1a;https://github.com/ 修改本地仓库用户名&#xff1a; git config --local…

【B站保姆级视频教程:Jetson配置YOLOv11环境(五)Miniconda安装与配置】

Jetson配置YOLOv11环境&#xff08;5&#xff09;Miniconda安装与配置 文章目录 0. Anaconda vs Miniconda in Jetson1. 下载Miniconda32. 安装Miniconda33. 换源3.1 conda 换源3.2 pip 换源 4. 创建环境5. 设置默认启动环境 0. Anaconda vs Miniconda in Jetson Jetson 设备资…

Cesium ArcGisMapServerImageryProvider API 介绍

作为一名GIS研究生&#xff0c;WebGIS 技术无疑是我们必学的核心之一。说到WebGIS&#xff0c;要提的就是 Cesium —— 这个让3D地球可视化变得简单又强大的工具。为了帮助大家更好地理解和使用 Cesium&#xff0c;我决定把我自己在学习 Cesium 文档过程中的一些心得和收获分享…

STM32-时钟树

STM32-时钟树 时钟 时钟

【Unity3D】实现横版2D游戏——单向平台(简易版)

目录 问题 项目Demo直接使用免费资源&#xff1a;Hero Knight - Pixel Art &#xff08;Asset Store搜索&#xff09; 打开Demo场景&#xff0c;进行如下修改&#xff0c;注意Tag是自定义标签SingleDirCollider using System.Collections; using System.Collections.Generic;…

基于UKF-IMM无迹卡尔曼滤波与交互式多模型的轨迹跟踪算法matlab仿真,对比EKF-IMM和UKF

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于UKF-IMM无迹卡尔曼滤波与交互式多模型的轨迹跟踪算法matlab仿真,对比EKF-IMM和UKF。 2.测试软件版本以及运行结果展示 MATLAB2022A版本运行 3.核心程序 .…

学习笔记 ---- 平衡树 总结

文章目录 平衡树的含义二叉搜索树 t r e a p treap treap S p l a y Splay Splay&#xff08;延伸树&#xff09;优化思想 S p l a y Splay Splay 的定义核心操作文艺平衡树&#xff08;序列操作&#xff09;练习题平衡树维护序列平衡树维护数集 F H Q t r e a p FHQ \ treap F…

Windows基础

一. Windows防火墙与Defender 介绍&#xff1a;Windows防火墙与Defender是Windows操作系统中两大重要的安全组件&#xff0c;它们共同工作以保护计算机免受各种网络威胁和病毒攻击。 Windows防火墙&#xff1a;Windows防火墙是一种软件防火墙&#xff0c;旨在监控和控制进出计…

(1)Linux高级命令简介

Linux高级命令简介 在安装好linux环境以后第一件事情就是去学习一些linux的基本指令&#xff0c;我在这里用的是CentOS7作演示。 首先在VirtualBox上装好Linux以后&#xff0c;启动我们的linux&#xff0c;输入账号密码以后学习第一个指令 简介 Linux高级命令简介ip addrtou…

人工智能|基本概念|人工智能相关重要概念---AI定义以及模型相关知识

一、 前言&#xff1a; 最近deepseek&#xff08;深度求索&#xff09;公司的开源自然语言处理模型非常火爆。 本人很早就对人工智能比较感兴趣&#xff0c;但由于种种原因没有过多的深入此领域&#xff0c;仅仅是做了一点初步的了解&#xff0c;借着这个deepseek&#xff0…

【疑海破局】一个注解引发的线上事故

【疑海破局】一个注解引发的线上事故 1、问题背景 在不久前一个阳光明媚的上午,我的思绪正在代码中游走、双手正在键盘上飞舞。突然,公司内部通讯工具上,我被拉进了一个临时工作群,只见群中产品、运营、运维、测试等关键人员全部严阵以待,我就知道大的可能要来了。果不其…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.1 NumPy高级索引:布尔型与花式索引的底层原理

2.1 NumPy高级索引&#xff1a;布尔型与花式索引的底层原理 目录 #mermaid-svg-NpcC75NxxU2mkB3V {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-NpcC75NxxU2mkB3V .error-icon{fill:#552222;}#mermaid-svg-NpcC75…

如何在 ACP 中建模复合罐

概括 本篇博文介绍了 ANSYS Composite PrepPost (ACP) 缠绕向导。此工具允许仅使用几个条目自动定义高压罐中常见的悬垂复合结构。 ACP 绕线向导 将必要的信息输入到绕组向导中。重要的是要注意“参考半径”&#xff0c;它代表圆柱截面的半径&#xff0c;以及“轴向”&#x…

【Linux】使用管道实现一个简易版本的进程池

文章目录 使用管道实现一个简易版本的进程池流程图代码makefileTask.hppProcessPool.cc 程序流程&#xff1a; 使用管道实现一个简易版本的进程池 流程图 代码 makefile ProcessPool:ProcessPool.ccg -o $ $^ -g -stdc11 .PHONY:clean clean:rm -f ProcessPoolTask.hpp #pr…

【算法-位运算】求数字的补数

文章目录 1. 题目2. 思路3. 代码4. 小结 1. 题目 476. 数字的补数 对整数的二进制表示取反&#xff08;0 变 1 &#xff0c;1 变 0&#xff09;后&#xff0c;再转换为十进制表示&#xff0c;可以得到这个整数的补数。 例如&#xff0c;整数 5 的二进制表示是 “101” &…

DeepSeek能下围棋吗?(续)

休息了一下&#xff0c;接着琢磨围棋&#xff0c;其实前面一篇里的规则有个漏洞的&#xff0c;就是邻居关系定义有问题&#xff0c;先回顾一下游戏规则&#xff1a; 游戏规则 定义&#xff1a; 1.数字对&#xff0c;是指两个1到9之间的整数组成的有序集合。可与记为(m,n)&…

[Collection与数据结构] B树与B+树

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

origin如何在已经画好的图上修改数据且不改变原图像的画风和格式

例如我现在的.opju文件长这样 现在我换了数据集&#xff0c;我想修改这两个图表里对应的算法里的数据&#xff0c;但是我还想保留这图像现在的形式&#xff0c;可以尝试像下面这样做&#xff1a; 右击第一个图&#xff0c;出现下面&#xff0c;选择Book[sheet1] 选择工作簿 出…