第一章 算法基础 前缀和

1、算法思路

1.一维前缀和

对于一个包含元素 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1,a2,...,an的数组a,设 S i = a 1 + a 2 + . . . + a i S_i = a_1 + a_2 + ... + a_i Si=a1+a2+...+ai,那么 S i S_i Si就是 [ a 1 , a 2 , . . . , a i ] [a_1,a_2,...,a_i] [a1,a2,...,ai]的前缀和。

  1. 如何求前缀和
    S i = a 1 + a 2 + . . . + a i = S i − 1 + a i S_i = a_1 + a_2 + ... + a_i = S_{i-1} + a_i Si=a1+a2+...+ai=Si1+ai
  2. 前缀和的作用
    记录下前缀和,可以在 O ( 1 ) O(1) O(1)的时间内,计算出一个区间的元素之和。
    例如我们想要求出 a l + a l + 1 + . . . + a r a_l + a_{l+1} + ... + a_r al+al+1+...+ar,可以利用前缀和
    S r − S l − 1 = a 1 + a 2 + . . . + a l − 1 + a l + . . . + a r − a 1 + a 2 + . . . + a l − 1 = a l + a l + 1 + . . . + a r S_r - S_{l - 1} = a_1 + a_2 + ...+a_{l -1} + a_{l} + ... + a_r - a_1 + a_2 + ... + a_{l -1} = a_l + a_{l+1} + ... + a_r SrSl1=a1+a2+...+al1+al+...+ara1+a2+...+al1=al+al+1+...+ar,这样就求得了这个区间和

2.二维前缀和

(下面i表示行,j表示列)
和一维前缀和类似, 对于一个包含元素 a i , j a_{i,j} ai,j的二维数组a,设 S i , j = a 0 , 0 + a 0 , 1 + . . . + a i , j S_{i,j} = a_{0,0} + a_{0,1} + ... + a_{i,j} Si,j=a0,0+a0,1+...+ai,j,那么 S i , j S_{i,j} Si,j就是这些元素的前缀和。用图片解释如下图

在这里插入图片描述
对于这个标红的位置,其前缀和为(1 + 2 + 3 + 5 + 6 + 7)= 24

  1. 如何求前缀和
    先说结论,结论之后我们找一个例子看看
    S i , j = S i , j − 1 + S i − 1 , j − S i − 1 , j − 1 + a i , j S_{i,j} = S_{i,j -1} + S_{i - 1,j} -S_{i-1,j-1} + a_{i,j} Si,j=Si,j1+Si1,jSi1,j1+ai,j
    对于标红的位置(1,2)来说,上式中 S i , j − 1 S_{i,j-1} Si,j1 S 1 , 1 S_{1,1} S1,1)即为标蓝的方格
    在这里插入图片描述
    S i − 1 , j ( S_{i-1,j}( Si1,j(S_{0,2} ) ) )即为下面的蓝色方格区域
    在这里插入图片描述
    二者之和即为
    在这里插入图片描述
    这里深颜色的地方代表的是上面两块的重合地带,加重了,所以要减去 S i − 1 , j − 1 S_{i-1,j-1} Si1,j1( S 0 , 1 S_{0,1} S0,1)
    在这里插入图片描述
    减完之后再加上 a i , j a_{i,j} ai,j本身,就求出了前缀和。
  2. 前缀和的作用
    其实作用跟一维类似,就是用来快速求出某个区域内的和

2、模板代码

基本不需要什么模板,理解了含义就能写出
一维情况

S[i] = a[1] + a[2] + ... a[i]
a[l] + ... + a[r] = S[r] - S[l - 1]

二维情况

S[i, j] = 第i行j列格子左上部分所有元素的和,按照上面的分析去求即可
以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵的和为:
S[x2, y2] - S[x1 - 1, y2] - S[x2, y1 - 1] + S[x1 - 1, y1 - 1]

3、参考资料

Acwing

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值