前缀和 差分

news2025/2/2 19:04:56

差分和前缀和都是算法里边比较重要的知识点,不过学习的难度并不高,这篇文章会讲解相关的内容。

1. 前缀和怎么玩

1)一维前缀和

在该数之前,包括该数的所有数之和,有点类似高中学的数列的前n项和Sn。

2)二维前缀和

根据原数组生成sum数组,sum[i][j]表示从(0, 0)到(i, j)这个范围内的累加和

求法:依次求 左 + 上 - 左上 + 自己,再从左到右,从上到下生成

*往往补第0行、第0列来减少条件判断

【图解】

Q:如果要求某个范围内的累加和怎么办?

设求(a, b)到(c, d)的累加和,则累加和就是

sum[c][d] - sum[a-1][d] - sum[c][b-1] + sum[a-1][b-1]

根据sum数组的定义和下面的图解就非常清晰了

图解如下:

【练习】

有一道模版题,大家可以试着做做:链接

核心的思路就是二维前缀和,我的代码如下: 

class NumMatrix {
public:
    vector<vector<int>> sum;
    NumMatrix(vector<vector<int>>& matrix) {
        int m = matrix.size();
        int n = matrix[0].size();
        sum.resize(m + 1, vector<int>(n + 1));
        
        // 第0行、第0列空出来,减少判断
        for (int a = 0, b = 1; a < m; a++, b++)
            for (int c = 0, d = 1; c < n; c++, d++)
                sum[b][d] = matrix[a][c];
        
        // 求前缀和
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= n; j++)
                sum[i][j] += sum[i - 1][j] +
                sum[i][j - 1] - sum[i - 1][j - 1];
    }

    int sumRegion(int row1, int col1, int row2, int col2) {
        row2++;
        col2++;
        return sum[row2][col2] - sum[row2][col1]
            - sum[row1][col2] + sum[row1][col1];
    }
};

2. 差分怎么玩

前缀和是为了下面学习差分做铺垫的,那么差分是什么玩意呢?

一般来说,差分分为3种类型,分别是一维差分、二维差分、等差差分

1)一维差分

首先,来看一个例子:

给定一个开始全为0的数组(设大小为8),在指定下标范围进行加减操作,求多次操作后的数组

分别对2~5下标对应的数进行加3,1~3下标加2,4~6下标减2

当然,你也可以每个动作都循环一次,但是那样代码写得有点挫,而差分就是解决这样一类的问题的好方法。

【使用方式】

在每个动作的左位置下标做对应的操作,在右位置的下一个数进行逆操作,所有操作一遍后,用前缀和加工。

这是什么意思,说的是人话吗?🤔

比如,对2~5下标对应的数进行加3,那么就在2位置加3,在6位置减3;(此为一次操作)

对1~3位置加2,就对应着1位置加2,4位置减2;(第二次操作)

对4~6位置减2,对应4位置减2,7位置加2。(第三次操作)

最后进行前缀和加工(此步骤可以在多次操作后进行)

【图解】

【原理】

操作方式就是如上,原理也很简单,因为一开始全是0,那么在进行前缀和操作时就不会受到初始值的影响,只会由我们自己的操作控制。

而在第一个位置加了3,那么经过前缀和的操作就会让该位置及其后的位置都加了3,而因为在最右的位置在往后就不用操作了,那么就需要它的逆操作来抵消了。

【练习】

leetcode_1109航班预订

核心思路就是一维差分 + 前缀和加工,其实就相当于模版题了

参考代码:

class Solution {
public:
    vector<int> corpFlightBookings(vector<vector<int>>& bookings, int n) {
        vector<int> sum(n + 2, 0);
        for(int i = 0; i < bookings.size(); i++)
        {
            sum[bookings[i][0]] += bookings[i][2];
            sum[bookings[i][1] + 1] -= bookings[i][2];
        }

        vector<int> ans;
        for(int i = 1; i <= n; i++)
        {
            sum[i] += sum[i - 1];
            ans.push_back(sum[i]);
        }
        
        return ans;
    }
};

2)二维差分

跟一维差分类似,也是在初始全为0的条件下,然后在给定两个坐标区间,进行加减操作,多次操作后,求变化后的数组

【使用方式】

设 (a, b) 到 (c, d) 的范围 + v

一次操作:  (a, b) + v 

(a, d+1) - v

(c+1, b) - v

(c+1, d+1) + v

···(多次操作)

最后要加工前缀和

其实原理跟一维差分是类似的,也是因为在前缀和的加工后,对于某个点的变化就成了一片区域的变化,而对于重叠的变化(减了2次)需要再处理

【图解】

【练习】

leetcode_2132贴邮票

核心:二维前缀和与二维差分的结合

思考逻辑:先不考虑邮票的重叠,直接把能贴的位置都贴上,其中判断能不能贴是根据区域前缀和是否为0,贴邮票二维差分的过程(对应四角处理),最后再前缀和加工

注意:此题要非常注意数组的范围,不然会越界

参考代码:链接(内含注释)

3)等差差分

这类问题相当考的较少,可以考虑先跳过

一般的问题描述是,一开始数组全为0,接下来有若干次(已知)操作,每次操作分别是在 l~r 范围上依次加上首项为s,末项为e,公差为d的等差数列,求多次操作后的数组

【使用方式】

arr[l] += s

arr[l + 1] += d - s

arr[r + 1] -= d + e

arr[r + 2] += e

多次操作后,再加工两次前缀和

【图解】

【练习】

luogu_P4231三步必杀

其实就是模板题,思路不难

注意数据量比较大,要用 long long

参考代码:链接

如果有问题可以在评论区一起讨论,对你有帮助的话不妨点个赞👍

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年美赛A题:资源可用性和性别比例 Resource Availability and Sex Ratios 思路模型代码解析

2024年美赛A题&#xff1a;资源可用性和性别比例 Resource Availability and Sex Ratios 思路模型代码解析 【点击最下方群名片&#xff0c;加入群聊&#xff0c;获取更多思路与代码哦~】 问题翻译 虽然一些动物物种存在于通常的雄性或雌性之外&#xff0c;但大多数物种在很大…

ncc匹配(二,补足旋转)

先看运行结果&#xff1a; 第一张图是基于形状匹配结果0.992&#xff0c;第二张是匹配结果的ncc结果&#xff0c;1 再看旋转后&#xff1a; 看到没&#xff0c;旋转后&#xff0c;基于形状匹配结果28度&#xff0c;0.517&#xff0c;根据匹配结果ncc结果是0.99 我们看到ncc以…

聊一聊Tomcat的架构和运行流程,尽量通俗易懂一点

1、Tomcat的架构 这里可以看出 A、一个Tomcat就是一个Server&#xff0c;一个Server下会有多个Service&#xff0c; B、Service只负责封装多个Connector和一个Container&#xff08;Service本身不是容器&#xff0c;可以看做只是用来包装Connector和Container的壳&#xff0c…

户外没有电源和网络,但需要安装监控系统,怎么办?太阳能智能监控系统给你解决

近期有粉丝给小编求助&#xff1a;需要在没网没电的户外进行智能监控的安装&#xff0c;不知道如何解决。收到粉丝的问题&#xff0c;小编立刻联系了技术人员给出方案。针对野外、户外等场景只需使用太阳能供电模组4G摄像机视频监控EasyCVR平台智能分析网关V4的架构&#xff0c…

Leetcode—2950. 可整除子串的数量【中等】Plus(前缀和题型)

2024每日刷题&#xff08;一零八&#xff09; Leetcode—2950. 可整除子串的数量 算法思想 让 f ( c ) d , 其中 d 1 , 2 , . . . , 9 f(c) d, 其中d 1, 2, ..., 9 f(c)d,其中d1,2,...,9. // f(c1) f(c2) ... f(ck) / k avg // > f(c1) f(c2) ... f(ck) - …

spring中生成jwtToken字符串以及解析手写通用工具类

当前使用JWT&#xff0c;肯定得提前准备jwt相关的导入依赖。 <!-- 关于jwt 生成令牌--> <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>${jjwt.version}</version> </dependency…

【前沿技术杂谈:开源软件】引领技术创新与商业模式的革命

【前沿技术杂谈&#xff1a;开源软件】引领技术创新与商业模式的革命 开源软件如何推动技术创新开源软件的开放性和协作精神促进知识共享和技术迭代推动关键技术的发展开源软件与新技术的融合 开源软件的商业模式开源软件的商业模式将开源软件与商业软件相结合 开源软件的安全风…

Acwing---798.差分矩阵

差分矩阵 1.题目2.基本思想3.代码实现 1.题目 输入一个 n n n 行 m m m列的整数矩阵&#xff0c;再输入 q q q 个操作&#xff0c;每个操作包含五个整数 x 1 , y 1 , x 2 , y 2 , c x1,y1,x2,y2,c x1,y1,x2,y2,c&#xff0c;其中 ( x 1 , y 1 ) (x1,y1) (x1,y1) 和 ( x …

C++——日期类

前言&#xff1a;哈喽小伙伴们&#xff0c;在上一篇文章中我们对C类与对象的前半段知识进行了简单的分享&#xff0c;其中比较重要的莫过于C类的六个默认成员函数。 所以这篇文章&#xff0c;我们通过实现一个完整的日期的操作&#xff0c;来对这些成员函数有一个更加深入的理…

nginx反向代理----->微服务网关----->具体微服务

今天&#xff0c;做项目的时候做项目的时候配路由出现bug&#xff0c;特此理顺一下从nginx到微服务网关再到微服务这一过程。 nginx配置 upstream admin-gateway{server localhost:21217; }server {listen 8803;location / {root F:/develop/admin-web/;index index.html;}…

strlen函数详解

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;c语言 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&a…

MATLAB实现二阶模糊逻辑控制系统仿真

1. 内容 假设某一工业过程可等效成以下二阶系统&#xff1a; 设计一个模糊控制器&#xff0c;使其能自动建立模糊规则库&#xff0c;保证控制规则如表1所示&#xff0c;这种规则可表示为&#xff1a; 式中&#xff0c;fix为取整函数&#xff1b;E为误差的模糊集&#xff1b;DE…

惯性导航---常用坐标系

惯性导航—常用坐标系 捷联惯导系统的导航解算中&#xff0c;常用到四个坐标系&#xff0c;接下来介绍四个坐标系定义及其表示符号。 1 地心惯性坐标系&#xff08;i系&#xff09; 惯性传感器的输出是以该坐标系为参考基准的。 原点X轴Z轴Y轴地球中心赤道平面内&#xff0c…

《数字化运维路线图》第三部分-数字化运维转型平台 震撼发布!

数字化转型已不再是企业追求效益最大化的手段&#xff0c;而是成为经济发展变革、提升国家数字竞争的核心动力。在此背景下&#xff0c;博睿数据继续发力&#xff0c;隆重推出「数字化运维转型平台」&#xff0c;汇聚了我们对数字化转型的深刻洞见与实践经验&#xff0c;以期为…

【android】 android->profile 查看内存泄露

目录 实例讲解 各字段解释 实例讲解 各字段解释 在 Android Studio 的 Profile 视图中&#xff0c;Arrange by Stack 用于对内存分配和释放事件进行堆栈排列&#xff0c;以便更好地了解内存使用情况。以下是表上各列的一般含义&#xff1a; 1. **Call Chart (调用图)**: …

开发桌面端应用,使用electron-vite构建项目真的是一绝!

技术栈&#xff1a;electron v28.2.1、react v18.2.0 构建工具&#xff1a;electron-vite v2.0.0 项目打包&#xff1a;electron-builder v24.9.1 本教程为项目工程的搭建&#xff0c;相关技术的知识请各自学习。 Vite在当下绝对是非常卓越的前端构建工具&#xff0c;很多项目…

小型内衣裤洗衣机哪个牌子好?家用小型洗衣机推荐

相信对于很多用户而言&#xff0c;宁愿强撑着疲惫的身子手洗内衣裤&#xff0c;也不愿把内衣裤与外穿衣物一起放进洗衣机洗。内衣裤与外穿衣物的脏污情况不同&#xff0c;内衣裤是贴身衣物&#xff0c;上面留有人体的汗液和分泌物&#xff0c;有可能带有大量真菌。而外衣上则是…

springboot146基于Spring Boot的可盈保险合同管理系统的设计与实现

可盈保险合同管理系统 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本可盈保险合同管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时…

MtfLive直播导航PHP源码,附带系统搭建教程

将自动采集斗鱼、虎牙、触手、YY、章鱼、电视直播按分类/关键词聚合&#xff0c;用户选择分类&#xff0c;可以观看到全网该关键词下正在直播的内容。 特点 PC站和H5移动站自适应 自动缓存&#xff0c;避免频繁抓取数据 自定义抓取采集规则&#xff0c;同时支持HTML和JSON …

【C++游戏开发-01】推箱子

C游戏开发 文章目录 C游戏开发[TOC](文章目录) 前言一、逻辑分析1.1地图实现1.2人物的移动1.2.1小人移动1.2.2其他移动 1.3墙壁的碰撞1.4箱子的推动1.4.1什么时候推箱子1.4.2什么情况可以推箱子 1.5胜利的判断1.6卡关的处理1.7关卡的切换 二、DEMO代码2.1游戏框架2.2各功能函数…