前缀和
-
对于一个序列
a
a
a,它的“前缀和”序列
s
s
s可以通过递推计算
s
[
i
]
=
∑
j
=
1
i
a
[
j
]
=
s
[
i
?
1
]
+
a
[
i
]
s[i] = \sum\limits_ {j = 1} ^ {i} a[j] = s[i - 1] + a[i]
s[i]=j=1∑i?a[j]=s[i?1]+a[i] -
区间和,即序列
a
a
a在
[
l
,
r
]
[l,r]
[l,r]之间的数之和,可以通过“前缀和”相减求得
∑
i
=
l
r
a
[
i
]
=
s
[
r
]
?
s
[
l
?
1
]
\sum\limits_ {i = l} ^ {r} a[i] = s[r] - s[l - 1]
i=l∑r?a[i]=s[r]?s[l?1]
二维前缀和
- 在二维数组中,二维前缀和如下:
s
[
i
,
j
]
=
∑
x
=
1
i
∑
y
=
1
i
a
[
i
,
j
]
=
s
[
i
?
1
,
j
]
+
s
[
i
,
j
?
1
]
?
s
[
i
?
1
,
j
?
1
]
+
a
[
i
,
j
]
s[i, j] = \sum\limits_ {x = 1} ^ {i} \sum\limits_ {y = 1} ^ {i} a[i, j] \\ = s[i - 1, j] + s[i, j - 1] - s[i - 1, j - 1] + a[i, j]
s[i,j]=x=1∑i?y=1∑i?a[i,j]=s[i?1,j]+s[i,j?1]?s[i?1,j?1]+a[i,j] - 区间和,以边长为
r
r
r的的正方形为例:
∑
x
=
i
?
r
+
1
i
∑
y
=
j
?
r
+
1
i
a
[
x
,
y
]
=
s
[
i
,
j
]
?
s
[
i
?
r
,
j
]
?
s
[
i
,
j
?
r
]
+
s
[
i
?
r
,
j
?
r
]
\sum\limits_{x = i - r + 1} ^ {i} \sum\limits_ {y = j - r + 1} ^ {i} a[x, y] \\ = s[i, j] - s[i - r, j] - s[i, j - r] + s[i - r, j - r]
x=i?r+1∑i?y=j?r+1∑i?a[x,y]=s[i,j]?s[i?r,j]?s[i,j?r]+s[i?r,j?r] -
O
(
N
2
)
O(N^2)
O(N2)递推求出二维前缀和,
O
(
N
2
)
O(N^2)
O(N2)枚举边长为
r
r
r的正方形的右下角坐标
(
i
,
j
)
(i, j)
(i,j),即可
O
(
1
)
O(1)
O(1)计算正方形内数字之和
差分
- 对于一个序列
a
a
a,定义基于
a
a
a的差分序列
b
b
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) - 前缀和与差分是互逆运算,差分序列的前缀和序列即为原序列
a
a
a,而前缀和序列的差分序列也是原序列
a
a
a
- 把序列
a
a
a的区间
[
l
,
r
]
[l, r]
[l,r]加上
d
d
d(区间修改),只要将其差分序列
b
l
+
d
b_l + d
bl?+d,
b
r
+
1
?
d
b_{r + 1} - d
br+1??d,其它元素不变,即将“区间修改”,变为“单点修改”
|