树状数组求区间最值

闲谈一下

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

查询一个数组的前缀和本来是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 &lt; 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 &lt; lowbit(x))。 x(a[x]),x20,x21,x22,,x2k<

  • 11
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
树状数组可以用来维护一个序列的前缀和,从而实现快速区间查询。但是如果想要区间最大值或最小值,需要进行一些修改。 具体做法如下: 1. 定义一个数组 $maxn$,表示每个节点的最大值。 2. 在更新某个节点的值时,同时更新其父节点的最大值。 3. 在查询区间最大值时,从右往左遍历每个节点,找到第一个其右边的兄弟节点的最大值大于等于查询区间左端点的位置,然后从该兄弟节点开始往右遍历,找到第一个其左边的兄弟节点的最大值小于等于查询区间右端点的位置。这两个位置之间的节点的最大值即为查询区间最大值。 示例代码: ```cpp const int N = 1e5; int a[N], c[N], maxn[N]; void update(int x, int v) { a[x] = v; while (x <= N) { c[x] += v; maxn[x] = max(maxn[x], v); x += x & -x; } } int query(int l, int r) { int res = INT_MIN; for (int i = r; i >= l; ) { if (i - (i & -i) + 1 >= l) { res = max(res, maxn[i]); i -= i & -i; } else { res = max(res, a[i]); i--; } } return res; } ``` 其中,$a$ 数组表示原始序列,$c$ 数组表示树状数组,$maxn$ 数组表示每个节点的最大值。在更新节点 $x$ 的值时,同时更新 $maxn$ 数组。在查询区间最大值时,从右往左遍历每个节点,找到第一个其右边的兄弟节点的最大值大于等于查询区间左端点的位置,然后从该兄弟节点开始往右遍历,找到第一个其左边的兄弟节点的最大值小于等于查询区间右端点的位置。这两个位置之间的节点的最大值即为查询区间最大值
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值