一维差分
问题背景
给定序列
a
a
a:
a
1
、
a
2
、
a
3
.
.
.
.
、
a
n
a_{1}、a_{2}、a_{3}....、a_{n}
a1、a2、a3....、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}
al−1基础上加了
b
l
、
b
l
+
1
、
b
l
+
2
.
.
.
b
r
b_{l}、b_{l+1}、b_{l+2}...b_{r}
bl、bl+1、bl+2...br
a
l
a_{l}
al到
a
r
a_{r}
ar之间的每个数
a
i
a_{i}
ai都在
a
l
−
1
a_{l-1}
al−1基础上加了
b
l
、
b
l
+
1
、
b
l
+
2
.
.
.
b
i
b_{l}、b_{l+1}、b_{l+2}...b_{i}
bl、bl+1、bl+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=al−1+bl+bl+1+bl+2+...+bi
(
l
≤
i
≤
r
)
(l≤i≤r)
(l≤i≤r)
所以想要在区间
[
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) O(n∗m)
- 转化为对矩阵 b b b的操作,时间复杂度为 O ( 1 ) O(1) O(1)
给以 ( 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矩阵的插入操作。