前缀和的逆操作——差分 思路

一维差分

问题背景

给定序列 a a a a 1 、 a 2 、 a 3 . . . . 、 a n a_{1}、a_{2}、a_{3}....、a_{n} a1a2a3....an
求一个序列 b b b,使得 a a a序列是 b b b序列的前缀和,对序列 b b b求前缀和,即为 a a a

应用

在序列 a a a中,给区间 [ l , r ] [l,r] [l,r]上的数全都加上常数 C C C

  • 直接对序列 a a a本身操作,需要 O ( n ) O(n) O(n)的时间
  • 转化为对序列 b b b的操作,只需要 O ( 1 ) O(1) O(1)的时间

因为从 a l a_{l} al a r a_{r} ar是在 a l − 1 a_{l-1} al1基础上加了 b l 、 b l + 1 、 b l + 2 . . . b r b_{l}、b_{l+1}、b_{l+2}...b_{r} blbl+1bl+2...br
a l a_{l} al a r a_{r} ar之间的每个数 a i a_{i} ai都在 a l − 1 a_{l-1} al1基础上加了 b l 、 b l + 1 、 b l + 2 . . . b i b_{l}、b_{l+1}、b_{l+2}...b_{i} blbl+1bl+2...bi
a r = a l − 1 + b l + b l + 1 + b l + 2 + . . . + b i a_{r}=a_{l-1}+b_{l}+b_{l+1}+b_{l+2}+...+b_{i} ar=al1+bl+bl+1+bl+2+...+bi ( l ≤ i ≤ r ) (l≤i≤r) (lir)
所以想要在区间 [ l , r ] [l,r] [l,r]上,使得 a [ i ] = a [ i ] + C a[i]=a[i]+C a[i]=a[i]+C,可以使 b [ l ] = b [ l ] + C b[l]=b[l]+C b[l]=b[l]+C
因为在区间 [ l , r ] [l,r] [l,r]上, a [ i ] a[i] a[i]的计算都会涉及到 b [ l ] b[l] b[l],也避免了对区间前面的值产生影响
而为了避免对区间后面的值产生影响,要使得 b [ r + 1 ] = b [ r + 1 ] − C b[r+1]=b[r+1]-C b[r+1]=b[r+1]C,从而抵消前面的 + C +C +C
综合:

给序列 a a a区间 [ l , r ] [l, r] [l,r]中的每个数加上 c c c B [ l ] + = c B[l] += c B[l]+=c, B [ r + 1 ] − = c B[r + 1] -= c B[r+1]=c

最后,再由 b b b序列反过来得到操作完之后的序列 a a a,即反推出前缀和数组。

b b b序列的初始化

b b b序列的初始化可以看成:

  • b b b数组初始时是全零的序列
  • 序列 a a a也是全零的序列,从左到右,每给 a [ i ] a[i] a[i]一个值,那么就相当于在序列 a a a的区间 [ i , i ] [i,i] [i,i]上加了常数 a [ i ] a[i] a[i],转化为对序列 b b b的操作,就是 b [ i ] + = a [ i ] b[i]+=a[i] b[i]+=a[i], b [ i + 1 ] − = a [ i ] b[i+1]-=a[i] b[i+1]=a[i]

二维差分

整体类比一维

问题背景

给定矩阵 a a a
要求一个矩阵 b b b,使得矩阵 a a a的每个元素是矩阵 b b b相应的前缀和

应用

在矩阵a中,要使 [ x 1 ] [ y 1 ] [x1][y1] [x1][y1]~ [ x 2 ] [ y 2 ] [x2][y2] [x2][y2]范围内的元素都加 c c c

  • 直接操作矩阵 a a a,时间复杂度为 O ( n ∗ m ) O(n*m) Onm
  • 转化为对矩阵 b b b的操作,时间复杂度为 O ( 1 ) O(1) O1

给以 ( x 1 , y 1 ) (x1, y1) (x1,y1)为左上角, ( x 2 , y 2 ) (x2, y2) (x2,y2)为右下角的子矩阵中的所有元素加上c:
b [ x 1 , y 1 ] + = c b[x1, y1] += c b[x1,y1]+=c, b [ x 2 + 1 , y 1 ] − = c b[x2 + 1, y1] -= c b[x2+1,y1]=c, b [ x 1 , y 2 + 1 ] − = c b[x1, y2 + 1] -= c b[x1,y2+1]=c, b [ x 2 + 1 , y 2 + 1 ] + = c b[x2 + 1, y2 + 1] += c b[x2+1,y2+1]+=c

b b b矩阵的初始化

b b b矩阵的初始化可以看成:

  • b b b数组初始时是全零的序列
  • 矩阵 a a a也是全零的序列,从左到右,从上到下,每给 a [ i ] [ j ] a[i][j] a[i][j]一个值,那么就相当于在矩阵 a a a的子矩阵 a [ i ] [ j ] a[i][j] a[i][j] a [ i ] [ j ] a[i][j] a[i][j]之间都加上了 a [ i ] [ j ] a[i][j] a[i][j],转化为对 b b b矩阵的插入操作。
  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Alkali!

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

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

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

打赏作者

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

抵扣说明:

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

余额充值