板块:基础算法、线性优化
难度:较易
前置知识: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[n−1],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[n−1]+a[n](n≥1,f[0]=0)
易得其时间复杂度为 O ( n ) O(n) O(n).
完成预处理后,我们将会面临 查询 的问题,对于一个区间 l ∼ r l\sim r l∼r,查询其区间前缀和的公式为:
s [ r ] − s [ l − 1 ] ( l ≥ 1 ) s[r]-s[l-1](l\geq 1) s[r]−s[l−1](l≥1)
易得其时间复杂度为 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][j−1] 存储的是 a [ 1 ] [ 1 ] ∼ a [ i ] [ j − 1 ] a[1][1]\sim a[i][j-1] a[1][1]∼a[i][j−1] 的前缀和,即黄色区域和红色区域; s [ i − 1 ] [ j ] s[i-1][j] s[i−1][j] 存储的是 a [ 1 ] [ 1 ] ∼ a [ i − 1 ] [ j ] a[1][1]\sim a[i-1][j] a[1][1]∼a[i−1][j] 的前缀和,即黄色区域和红色区域.这个推导类似于在电脑中进行框选操作时拖动鼠标的而显示出的矩形区域.如果我们将 s [ i ] [ j − 1 ] s[i][j-1] s[i][j−1] 和 s [ i − 1 ] [ j ] s[i-1][j] s[i−1][j] 相加,我们不难得到绿色区域、红色区域和两个黄色区域的前缀和,也就发现多出了一个黄色区域,因此减去 s [ i − 1 ] [ j − 1 ] s[i-1][j-1] s[i−1][j−

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

363

被折叠的 条评论
为什么被折叠?



