树状数组求区间最值

闲谈一下

树状数组最基本的功能是加速前缀和的更新。

查询一个数组的前缀和本来是O(1)的复杂度,用树状数组则为O(logn)。
但树状数组优点在于单点更新时复杂度为O(logn),而正常的为O(n),这也就使得树状数组能够进行大规模的更新。
虽然查询速度(O(logn))稍有些慢(相对于O(1)而言),但依旧可以用于大规模的查询。

总之,遇到有不断更新的数组前缀和时可以考虑树状数组。

树状数组求区间最值

就像线段树一样,我们一开始接触线段树时一般也是求区间和,学会以后发现仅仅需要将sum改成max就能求出区间最值,既然可以将树状数组理解为线段树的单点更新版本,那树状数组又如何呢?

事实上,树状数组也仅需要作出少许修改即可实现单点更新+区间查询求最值。
(如果只需要前缀最值那么就真的只需要将修改及查询操作中的 + + +号改为 m a x / m i n max/min max/min,极为简洁)

单点更新

在最值的单点更新时,不像前缀和的单点更新那样仅仅需要考虑当前点修改以后会对后面的的数产生什么影响。

而需要额外考虑的是当前点的修改究竟由什么决定。

前缀和只需要给定一个增量(不是末状态),然后即可对x处(以及后面所有的x+lowbit(x)处)进行修改。

但对于区间最值而言,b[x]数组表示[x-lowbit(x)+1, x]这个区间的最值,因此不知道x处(以及后面所有的x+lowbit(x)处)在改变时的增量是多少。想得到x处的末状态只能通过与这个区间的所有值再进行一个求最值。

是不是一眼看上去复杂度有点高?仅仅单点更新就到达了nlogn了。

但值得庆幸的是,既然是树状数组,那一定有她特色的地方

可以发现:在x处求末状态时,对它能产生影响的究竟有哪些点?肯定不是[x-lowbit(x)+1, x]这整个区间。

有影响的只有: x ( a [ x ] ) , x − 2 0 , x − 2 1 , x − 2 2 , … , x − 2 k ( k 满 足 2 k < l o w b i t ( x ) ) 。 x(a[x]), x-2^0, x-2^1, x-2^2, \dots, x-2^k (k满足2^k < lowbit(x))。 x(a[x]),x20,x21,x22,,x2k<

你可能感兴趣的:(算法(Lazy),树状数组,区间最值)