Fenwick原生功能是单点修改+查询前缀和,如何将其转化成区间修改区间查询?
d[i] = a[i] - a[i - 1];
如果Fenwick维护的是d[i], 那么查询的就是d[i]的前缀和, 也就是a[i];
显然:d[i]的前缀和的前缀和就是前i个数的和。
那么怎么样查询一个区间呢?
直观上来感受, 需要将d[i]再求一遍和, 最后应该是
i
∗
d
[
i
]
i * d[i]
i∗d[i]这种模样的东西。
把a[i]的前缀和用d[i]表示一下看看能发现什么规律:
∑
i
=
1
n
a
[
i
]
=
∑
i
=
1
n
∑
j
=
1
i
d
[
i
]
=
n
d
[
1
]
+
(
n
−
1
)
d
[
2
]
+
.
.
.
+
2
d
[
n
−
1
]
+
d
[
n
]
\sum_{i=1}^{n}a[i] = \sum_{i = 1}^{n}\sum_{j = 1}^{i}d[i]=nd[1]+(n-1)d[2]+...+2d[n-1]+d[n]
i=1∑na[i]=i=1∑nj=1∑id[i]=nd[1]+(n−1)d[2]+...+2d[n−1]+d[n]
得到了
(
n
−
i
+
1
)
d
[
i
]
(n - i + 1)d[i]
(n−i+1)d[i]这个东西。设
x
[
i
]
=
(
n
−
i
+
1
)
d
[
i
]
x[i] = (n - i + 1)d[i]
x[i]=(n−i+1)d[i]。那么:
∑
i
=
1
n
a
[
i
]
=
∑
i
=
1
n
x
[
i
]
\sum_{i=1}^{n}a[i] = \sum_{i = 1}^{n}x[i]
i=1∑na[i]=i=1∑nx[i]
那么把x[i]扔到Fenwick里面,Fenwick就能对x[i]单点更新区间查询了。
显然对a[i]的区间更新可以转化为区间端点处的d[i]的单点更新,也就是端点处 x [ i ] = ( n − i + 1 ) d [ i ] x[i] = (n - i + 1)d[i] x[i]=(n−i+1)d[i]的更新。
对a[i]的区间查询能转化为对x[i]的前缀和查询。