0x03
前缀和与差分
1.前缀和
对于一个给定的数组A,它的前缀和数列S是通过递推能求出的基本信息之一:
S
[
i
]
=
∑
j
=
1
i
A
[
j
]
S
[
i
]
=
S
[
i
−
1
]
+
A
[
i
]
S[i]=\sum_{j=1}^iA[j] \\ S[i]=S[i-1]+A[i]
S[i]=j=1∑iA[j]S[i]=S[i−1]+A[i]
一个部分和,即数列A某个下标区间内数的和,可以表示为前缀和相减的形式:
s
u
m
(
l
,
r
)
=
∑
i
=
l
r
A
[
i
]
=
S
[
r
]
−
S
[
l
−
1
]
sum(l,r)=\sum_{i=l}^{r}A[i]=S[r]-S[l-1]
sum(l,r)=i=l∑rA[i]=S[r]−S[l−1]
在二维数组(矩阵)中,可类似求出二维前缀和,进一步计算出二维部分和。
S
[
i
]
[
j
]
=
∑
x
=
1
i
∑
y
=
1
j
A
[
x
]
[
y
]
S
[
i
]
[
j
]
=
S
[
i
−
1
]
[
j
]
+
S
[
i
]
[
j
−
1
]
−
S
[
i
−
1
]
[
j
−
1
]
+
A
[
i
]
[
j
]
S[i][j]=\sum_{x=1}^{i}\sum_{y=1}^{j}A[x][y] \\ S[i][j]=S[i-1][j]+S[i][j-1]-S[i-1][j-1]+A[i][j]
S[i][j]=x=1∑iy=1∑jA[x][y]S[i][j]=S[i−1][j]+S[i][j−1]−S[i−1][j−1]+A[i][j]
前缀和可以求出某个固定长度区间里的最值。
2.差分
给定一个数列A,它的差分数列B定义为:
B
[
1
]
=
A
[
1
]
,
B
[
i
]
=
A
[
i
]
−
A
[
i
−
1
]
(
2
≤
i
≤
n
)
B[1]=A[1],B[i]=A[i]-A[i-1](2\le i\le n)
B[1]=A[1],B[i]=A[i]−A[i−1](2≤i≤n)
“前缀和”与“差分”是一对互逆运算,差分序列B的前缀和序列是原数列A,前缀和序列S的差分序列也是原序列。
序列A的区间[l,r]
所有数加上d,其差分序列变化为
B
l
+
d
B_l+d
Bl+d 、
B
r
+
1
−
d
B_{r+1}-d
Br+1−d,其他位置不变,把“区间操作”变化为“单点操作”,降低求解难度。