一维前缀和
包含 n 个元素的数组
a
r
r
arr
arr
询问 q 次
[
L
,
R
]
[L, R]
[L,R](下标从 L 到 R)的区间和
s
u
m
[
L
,
R
]
sum[L, R]
sum[L,R]
时间复杂度为
O
(
n
q
)
O(nq)
O(nq)
例如:
给出数组 arr : 1 3 7 5 2
询问区间和:
[2, 4] = 7 + 5 + 2 = 14
[0, 3] = 1 + 3 + 7 + 5 = 16
[3, 4] = 5 + 2 = 7
下面给出前缀和计算公式:
s
u
m
[
i
]
=
{
s
u
m
[
i
−
1
]
+
a
r
r
[
i
]
,
i
>
0
a
r
r
[
0
]
,
i
=
0
sum[i] = \begin{cases} sum[i-1] + arr[i], & i > 0\\ arr[0], & i = 0\\ \end{cases}
sum[i]={sum[i−1]+arr[i],arr[0],i>0i=0
那么,计算区间和
s
u
m
[
L
,
R
]
sum[L, R]
sum[L,R] 即可用下面公式计算得到。
s
u
m
[
L
,
R
]
=
{
s
u
m
[
R
]
−
s
u
m
[
L
−
1
]
,
L
>
0
s
u
m
[
R
]
,
L
=
0
sum[L, R] = \begin{cases} sum[R] - sum[L-1], & L > 0\\ sum[R], & L = 0\\ \end{cases}
sum[L,R]={sum[R]−sum[L−1],sum[R],L>0L=0
数组 arr : 1 3 7 5 2
前缀和 sum : 1 4 11 16 18
s
u
m
[
2
,
4
]
=
s
u
m
[
4
]
−
s
u
m
[
1
]
=
18
−
4
=
14
sum[2, 4] = sum[4] - sum[1] = 18 - 4 = 14
sum[2,4]=sum[4]−sum[1]=18−4=14
s
u
m
[
0
,
3
]
=
s
u
m
[
3
]
=
16
=
16
sum[0, 3] = sum[3] = 16 = 16
sum[0,3]=sum[3]=16=16
s
u
m
[
3
,
4
]
=
s
u
m
[
4
]
−
s
u
m
[
2
]
=
18
−
11
=
7
sum[3, 4] = sum[4] - sum[2] = 18 - 11 = 7
sum[3,4]=sum[4]−sum[2]=18−11=7
一维差分
包含 n 个元素的数组
a
r
r
arr
arr
给出差分数组:
d
[
i
]
=
{
a
r
r
[
i
]
−
a
r
r
[
i
−
1
]
,
i
>
0
a
r
r
[
i
]
,
i
=
0
d[i] = \begin{cases} arr[i] - arr[i-1], & i > 0\\ arr[i], & i = 0\\ \end{cases}
d[i]={arr[i]−arr[i−1],arr[i],i>0i=0
数组
a
r
r
arr
arr:1 3 7 5 2
差分
d
d
d:1 2 4 -2 -3
计算差分的前缀和
s
u
m
d
sum_d
sumd:1 3 7 5 2
,可以发现差分的前缀和
s
u
m
d
sum_d
sumd 与
a
r
r
arr
arr 相同。
现在若需要做 m 个操作 a r r [ L , R ] + v arr[L, R] + v arr[L,R]+v( a r r arr arr下标从 L L L 到 R R R 之间的值加个常数 v v v),那么时间复杂度为 O ( n m ) O(nm) O(nm)
现给出 3 个操作: a r r [ 2 , 4 ] + 5 arr[2, 4] + 5 arr[2,4]+5, a r r [ 1 , 3 ] + 2 arr[1, 3] + 2 arr[1,3]+2, a r r [ 0 , 2 ] − 3 arr[0, 2] - 3 arr[0,2]−3,即
arr[0] - 3;
arr[1] + 2 - 3;
arr[2] + 5 + 2 - 3;
arr[3] + 5 + 2;
arr[4] + 5;
那么数组
a
r
r
arr
arr 变为 -2, 2, 11, 12, 7
利用差分,给出结论:
a
r
r
[
L
,
R
]
+
v
⟺
d
[
L
]
+
v
,
d
[
R
+
1
]
−
v
arr[L, R] + v \iff d[L] + v, d[R+1] - v
arr[L,R]+v⟺d[L]+v,d[R+1]−v
a
r
r
[
L
,
R
]
+
v
⟺
{
d
[
L
]
+
v
,
d
[
R
+
1
]
−
v
,
i
>
0
d
[
L
]
+
v
,
R
=
n
−
1
arr[L, R] + v \iff \begin{cases} d[L] + v, d[R+1] - v, & i > 0\\ d[L] + v, & R = n-1\\ \end{cases}
arr[L,R]+v⟺{d[L]+v,d[R+1]−v,d[L]+v,i>0R=n−1
如例子中:
a
r
r
[
2
,
4
]
+
5
⟺
d
[
2
]
+
5
arr[2, 4] + 5 \iff d[2] + 5
arr[2,4]+5⟺d[2]+5
a
r
r
[
1
,
3
]
+
2
⟺
d
[
1
]
+
2
,
d
[
4
]
−
2
arr[1, 3] + 2 \iff d[1] + 2, d[4] - 2
arr[1,3]+2⟺d[1]+2,d[4]−2
a
r
r
[
0
,
2
]
−
3
⟺
d
[
0
]
−
3
,
d
[
3
]
+
3
arr[0, 2] - 3 \iff d[0] - 3, d[3] + 3
arr[0,2]−3⟺d[0]−3,d[3]+3
得到
d
d
d:-2 4 9 1 -5
计算新的差分
d
d
d 的前缀和
s
u
m
d
sum_d
sumd:-2 2 11 12 7
,正好是经过
a
r
r
[
2
,
4
]
+
5
arr[2, 4] + 5
arr[2,4]+5,
a
r
r
[
1
,
3
]
+
2
arr[1, 3] + 2
arr[1,3]+2,
a
r
r
[
0
,
2
]
−
3
arr[0, 2] - 3
arr[0,2]−3 之后的
a
r
r
arr
arr。