首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

前缀和与差分

编程知识
2024年07月27日 19:51

前缀和与差分

前缀和

定义:前缀和可以简单理解为「数列的前 n 项的和」,是一种重要的预处理方式,能大大降低查询的时间复杂度。

一维前缀和

模板

for (int i = 1; i <= n; i++) 
        sum[i] = sum[i - 1] + a[i];

时间复杂度:O(n)

原理

数组sum用于储存前 i 个元素的和, 数组a为原数组
sum[0] = a[0] = 0
sum[1] = a[1]
sum[2] = sum[1] + a[2] = a[1] + a[2]
sum[3] = sum[2] + a[3] = a[1] + a[2] + a[3]
sum[n] = sum[n - 1] + a[n] = a[1] + ..... + a[n]
由此我们可以得出:sum[i] = sum[i - 1] + a[i] 这一递推公式

模板题:一维前缀和

二维前缀和

模板

for (int i = 1;i <= n;i++)
        for (int j = 1;j <= m;j++)
            sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + a[i][j];

时间复杂度:O(n * m)

原理

如图所示,黑色边框为a[1][1]到a[i][j]之间所有元素的和(sum[i][j]),蓝色边框为a[1][1]到a[i - 1][j]之间所有元素的和(sum[i - 1][j]),橙色边框为a[1][1]到a[i][j - 1]之间所有元素的和(sum[i][j - 1])。
观察图的面积关系,我们可以得到这一递推关系:

sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + a[i]

这一递推关系即为二维前缀和的递推公式。

模板题:二维前缀和

与前缀和有关的题目

简单的D题

Codeforces Round 961 (Div. 2) B1. Bouquet (Easy Version)

差分

类似于数学中的求导和积分,差分可以看成前缀和的逆运算。

一维差分

模板

void insert(int l, int r, int y)
{
    s[l] = s[l] + y;
    s[r + 1] = s[r + 1] - y;
}

原理

一维差分数组其实就是原数组中该位置的元素减去上一位置的元素
如代码所示:
数组s为差分数组,数组a为原数组。

void insert(int l, int r, int y)
{
   s[l] = s[l] + y;
   s[r + 1] = s[r + 1] - y;
}

for (int i = 1;i <= n;i++)
     insert(i, i, a[i]);

在对数组a的遍历之时,差分数组s在 i 的位置加上原数组a在 i 位置的值,在 i + 1 位置减去原数组a在 i 位置的值,同理在 i - 1 位置时,s在 i - 1 的位置也减去了原数组在 i - 1 位置的值, 因此 s[i] = a[i] - a[i - 1]。

模板题:一维差分

二维差分

模板

void insert(int x1, int y1, int x2, int y2, int y)
{
    s[x1][y1] = s[x1][y1] + y;
    s[x2 + 1][y1] = s[x2 + 1][y1] - y;
    s[x1][y2 + 1] = s[x1][y2 + 1] - y;
    s[x2 + 1][y2 + 1] = s[x2 + 1][y2 + 1] + y;
}

原理

二维差分可以类似于一维差分进行理解

void insert(int x1, int y1, int x2, int y2, int y)
{
   s[x1][y1] = s[x1][y1] + y;   
   s[x2 + 1][y1] = s[x2 + 1][y1] - y;   
   s[x1][y2 + 1] = s[x1][y2 + 1] - y;
   s[x2 + 1][y2 + 1] = s[x2 + 1][y2 + 1] + y;
}
 
for (int i = 1;i <= n;i++)
   for (int j = 1;j <= m;j++)
         insert(i, j, i, j, q[i][j]);

s[x1][ y1 ] +=c ; 让整个s数组中蓝色矩形面积的元素都加上了c。
s[x1,][y2+1]-=c ; 让整个s数组中绿色矩形面积的元素再减去c,使其内元素不发生改变。
s[x2+1][y1]- =c ; 让整个s数组中紫色矩形面积的元素再减去c,使其内元素不发生改变。
s[x2+1][y2+1]+=c; 让整个s数组中红色矩形面积的元素再加上c,红色内的相当于被减了两次,再加上一次c,才能使其恢复。

模板题:二维差分

与差分有关的题目

最高的牛

From:https://www.cnblogs.com/APFLY/p/18327456
本文地址: http://www.shuzixingkong.net/article/493
0评论
提交 加载更多评论
其他文章 Git的存储原理
目录Git 设计原理Git vs SVNGit 存储模型.git 目录结构Git 基本数据对象Git 包文件Git 引用 Git 设计原理 概括的讲,Git 就是一个基于快照的内容寻址文件系统。 往下慢慢看。 Git vs SVN Git 出现前,主流版本控制系统(SVN...)一般为基于增量(de
Git的存储原理 Git的存储原理 Git的存储原理
自写ApiTools工具,功能参考Postman和ApiPost
近日在使用ApiPost的时候,发现新版本8和7不兼容,也就是说8不支持离线操作,而7可以。 我想说,我就是因为不想登录使用才从Postman换到ApiPost的。 众所周知,postman时国外软件,登录经常性抽风,离线支持也不太好。 所以使用apipost,开始用apipost7一直很好用。可是
自写ApiTools工具,功能参考Postman和ApiPost 自写ApiTools工具,功能参考Postman和ApiPost
Android低功耗子系统的投票机制以及触发进入系统休眠的过程
从kernel角度看,系统是否进入休眠应该由内核来控制,因此Linux引入了 wakeup source以及autosleep机制 关于wakeup source的介绍,请参考: Wakeup Source框架设计与实现 关于autosleep机制,请参考:autosleep框架设计与实现 在内核中
Android低功耗子系统的投票机制以及触发进入系统休眠的过程 Android低功耗子系统的投票机制以及触发进入系统休眠的过程 Android低功耗子系统的投票机制以及触发进入系统休眠的过程
Java SE 文件上传和文件下载的底层原理
1. Java SE 文件上传和文件下载的底层原理 @目录1. Java SE 文件上传和文件下载的底层原理2. 文件上传2.1 文件上传应用实例2.2 文件上传注意事项和细节3. 文件下载3.1 文件下载应用实例3.2 文件下载注意事项和细节4. 总结:5. 最后: 2. 文件上传 文件的上传和下
Java SE 文件上传和文件下载的底层原理 Java SE 文件上传和文件下载的底层原理 Java SE 文件上传和文件下载的底层原理
暑假java自学进度总结03
一.今日所学: 1.标识符命名规则: 必须: 1&gt;由数字,字母,下划线,美元符组成; 2&gt;不能以数字开头; 3&gt;不能是关键字; 4&gt;区分大小写; 建议: 1&gt;命名方法,变量时用小驼峰命名法: *1.标识符是一个单词时,全部小写 *2.标识符是多个单词组合时,第一个单词小
2024-07-27:用go语言,给定一个正整数数组,最开始可以对数组中的元素进行增加操作,每个元素最多加1。 然后从修改后的数组中选出一个或多个元素,使得这些元素排序后是连续的。 要求找出最多可以选
2024-07-27:用go语言,给定一个正整数数组,最开始可以对数组中的元素进行增加操作,每个元素最多加1。 然后从修改后的数组中选出一个或多个元素,使得这些元素排序后是连续的。 要求找出最多可以选出的元素数量。 输入:nums = [2,1,5,1,1]。 输出:3。 解释:我们将下标 0 和
2024-07-27:用go语言,给定一个正整数数组,最开始可以对数组中的元素进行增加操作,每个元素最多加1。 然后从修改后的数组中选出一个或多个元素,使得这些元素排序后是连续的。 要求找出最多可以选 2024-07-27:用go语言,给定一个正整数数组,最开始可以对数组中的元素进行增加操作,每个元素最多加1。 然后从修改后的数组中选出一个或多个元素,使得这些元素排序后是连续的。 要求找出最多可以选
利用Elasticsearch实现地理位置、城市搜索服务
最近用到一些简单的地理位置查询接口,基于当前定位获取用户所在位置信息(省市区),然后基于该信息查询当前区域的......提供服务。 然后就自己研究了下GIS,作为一个程序员。自己能不能实现这个功能呢?答案当然是可以。立即开干。 思路:找到数据,写入数据库,利用Elasticsearch强大的搜索能力
利用Elasticsearch实现地理位置、城市搜索服务 利用Elasticsearch实现地理位置、城市搜索服务
Python 实现行为驱动开发 (BDD) 自动化测试详解
​ 在当今的软件开发领域,行为驱动开发(Behavior Driven Development,BDD)作为一种新兴的测试方法,逐渐受到越来越多开发者的关注和青睐。Python作为一门功能强大且易于使用的编程语言,在实现BDD方面也有着独特的优势。那么,如何利用Python实现BDD自动化测试呢?本
Python 实现行为驱动开发 (BDD) 自动化测试详解 Python 实现行为驱动开发 (BDD) 自动化测试详解 Python 实现行为驱动开发 (BDD) 自动化测试详解