C/C++教程

Fenwick啊啊啊

本文主要是介绍Fenwick啊啊啊,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

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∑n​a[i]=i=1∑n​j=1∑i​d[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∑n​a[i]=i=1∑n​x[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]的前缀和查询。

这篇关于Fenwick啊啊啊的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!