【OI学习笔记】基础算法-前缀和与差分算法

前缀和是一种优化算法的时间复杂度的预处理思想,用于线性优化、求和等,一维前缀和的时间复杂度为O(n),二维前缀和的预处理递推公式描述了矩阵区域和的计算。差分是前缀和的逆运算,常用于区间操作的优化,一维差分可以通过构造差分数组并求前缀和来实现原数组的区间操作。二维差分类似,适用于二维矩阵的子区域操作。

板块:基础算法、线性优化
难度:较易
前置知识:C++基础语法

一、前缀和

1、定义

  • 在一维空间中,对于一个数据总量为 n n n 的数组 a a a,有数据 a [ 1 ] , a [ 2 ] , a [ 3 ] , . . . , a [ n − 1 ] , a [ n ] a[1],a[2],a[3],...,a[n-1],a[n] a[1],a[2],a[3],...,a[n1],a[n],定义一个数组 s u m sum sum s u m [ i ] sum[i] sum[i] 存储 a [ 1 ] ∼ a [ i ] a[1] \sim a[i] a[1]a[i] 的数据总和,我们就称 s u m sum sum a a a 的前缀和.

2.本质与应用领域

对于数组:

1 2 3 4 5 6 7

根据定义,我们计算出它各项所对应的前缀和应该是:

1 3 6 10 15 21 28
1 1+2 3+3 6+4 10+5 15+6 21+7

不难发现,前缀和的本质就是 递推.从前往后依次计算出前缀和.前缀和是一种思想,它是一种对算法进行时间优化的预处理数据的思想.前缀和的应用领域很宽广,比如用于线性优化、求和、预处理数据等.

3.一维前缀和

上文中我们所举的数组便是典型的一维前缀和,其 预处理递推公式 为: f [ n ] = f [ n − 1 ] + a [ n ] ( n ≥ 1 , f [ 0 ] = 0 ) f[n]=f[n-1]+a[n](n \geq1,f[0]=0) f[n]=f[n1]+a[n](n1,f[0]=0)
易得其时间复杂度为 O ( n ) O(n) O(n).
完成预处理后,我们将会面临 查询 的问题,对于一个区间 l ∼ r l\sim r lr,查询其区间前缀和的公式为:
s [ r ] − s [ l − 1 ] ( l ≥ 1 ) s[r]-s[l-1](l\geq 1) s[r]s[l1](l1)
易得其时间复杂度为 O ( 1 ) O(1) O(1).

4.二维前缀和

二维前缀和和一维前缀和同理,需要推导出预处理递推公式和查询公式.
如下图,我们需要递推 a [ 1 ] [ 1 ] ∼ a [ i ] [ j ] a[1][1]\sim a[i][j] a[1][1]a[i][j] 的前缀和即 s [ i ] [ j ] s[i][j] s[i][j] .由图示可知, s [ i ] [ j − 1 ] s[i][j-1] s[i][j1] 存储的是 a [ 1 ] [ 1 ] ∼ a [ i ] [ j − 1 ] a[1][1]\sim a[i][j-1] a[1][1]a[i][j1] 的前缀和,即黄色区域和红色区域; s [ i − 1 ] [ j ] s[i-1][j] s[i1][j] 存储的是 a [ 1 ] [ 1 ] ∼ a [ i − 1 ] [ j ] a[1][1]\sim a[i-1][j] a[1][1]a[i1][j] 的前缀和,即黄色区域和红色区域.这个推导类似于在电脑中进行框选操作时拖动鼠标的而显示出的矩形区域.如果我们将 s [ i ] [ j − 1 ] s[i][j-1] s[i][j1] s [ i − 1 ] [ j ] s[i-1][j] s[i1][j] 相加,我们不难得到绿色区域、红色区域和两个黄色区域的前缀和,也就发现多出了一个黄色区域,因此减去 s [ i − 1 ] [ j − 1 ] s[i-1][j-1] s[i1][j

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

oier_Asad.Chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值