树状数组求区间最大值一类问题
2013-01-24 08:44
344 查看
树状数组(Binary Index Tree)利用二进制的一些性质巧妙的划分区间,是一种编程,时间和空间上都十分理想的求区间和的算法,同样我们可以利用树状数组优美的区间划分方法来求一个序列的最值
约定以 num[] 表示原数组, 以 idx[] 表示索引数组, Lowbit(x)=x&(-x)
树状数组求和时通过构造数组 idx[] 使 idx[k]=sum(num[tk]), tk [k-Lowbit(k)+1,k], 使用同样的方法构造最值索引数组:
以最大值为例, 先讨论询问过程中不对数组做任何修改的情况, 用 idx[k] 记录 [k-Lowbit(k)+1,k] 区间内的最大值, 可以仿照求和时的方法得到:
这种方法在每次调用该函数前都必须对数组进行初始化, 这样对于数据范围比较大的时候不是很优美, 这样我们可以改为:
这样, 在更新到第k个数时, 所有 t(t<k) 都已经是正确的值了, 不存在上面那个函数的情况了
然后再来看查询的问题, 对于区间 [l,r] 把该区间转化为多个的小区间再进行求最值, 方法是从后往前对每一个索引数的范围进行判断, 如在进行到第k项时,该数控制的范围是 [k-Lowbit(k)+1,k], 如果k-Lowbit(k)+1在所求的范围内的话则将该区间的最值加入最值的判断,然后转至地k-Lowbit(k),否则的话就只对第k个数进行最值判断,然后转至k-1,具体实现如下:
该查询的复杂度为log(n)
st算法的复杂度 O(nlog(n)) / O(1) , 线段树为 O(nlog(n)) / (log(n)),树状数组 O(<nlog(n)) / O(log(n))
空间复杂度 st 为 O(nlog(n)), 线段树 O(n),常数较大 , 树状数组是 O(n)
编程上 st 和 树状数组 都比较容易实现,线段树代码较长
另外线段树灵活性较大
PKU 3264 题:
st Memory: 6372K Time: 1250MS 964B
BIT Memory: 716K Time: 1282MS 933B
SegTree 未测,要比st更大
然后我们可以进一步扩展到边查询边修改的情况
每次直接去更新父亲节点自然是不行的, 为了维护索引数组的正确性,我们在对每个父亲节点进行更新时都要查询他的所有儿子节点,在其中取最优值, 得到代码如下:
复杂度为 O(log^2(n)), HDU 1754 I hate it 437MS 1776K
另外,该方法还有一个减枝, 很容易想到,在求最大值时,当某个值更新的值大于原值的时候是没有必要再去查询儿子节点的,所以内部循环可加一个判断来判定是否需要扫描儿子节点,可能是数据问题,该题时间并没有大的变化
转载请注明出处:/article/7053634.html
约定以 num[] 表示原数组, 以 idx[] 表示索引数组, Lowbit(x)=x&(-x)
树状数组求和时通过构造数组 idx[] 使 idx[k]=sum(num[tk]), tk [k-Lowbit(k)+1,k], 使用同样的方法构造最值索引数组:
以最大值为例, 先讨论询问过程中不对数组做任何修改的情况, 用 idx[k] 记录 [k-Lowbit(k)+1,k] 区间内的最大值, 可以仿照求和时的方法得到:
然后再来看查询的问题, 对于区间 [l,r] 把该区间转化为多个的小区间再进行求最值, 方法是从后往前对每一个索引数的范围进行判断, 如在进行到第k项时,该数控制的范围是 [k-Lowbit(k)+1,k], 如果k-Lowbit(k)+1在所求的范围内的话则将该区间的最值加入最值的判断,然后转至地k-Lowbit(k),否则的话就只对第k个数进行最值判断,然后转至k-1,具体实现如下:
st算法的复杂度 O(nlog(n)) / O(1) , 线段树为 O(nlog(n)) / (log(n)),树状数组 O(<nlog(n)) / O(log(n))
空间复杂度 st 为 O(nlog(n)), 线段树 O(n),常数较大 , 树状数组是 O(n)
编程上 st 和 树状数组 都比较容易实现,线段树代码较长
另外线段树灵活性较大
PKU 3264 题:
st Memory: 6372K Time: 1250MS 964B
BIT Memory: 716K Time: 1282MS 933B
SegTree 未测,要比st更大
然后我们可以进一步扩展到边查询边修改的情况
每次直接去更新父亲节点自然是不行的, 为了维护索引数组的正确性,我们在对每个父亲节点进行更新时都要查询他的所有儿子节点,在其中取最优值, 得到代码如下:
另外,该方法还有一个减枝, 很容易想到,在求最大值时,当某个值更新的值大于原值的时候是没有必要再去查询儿子节点的,所以内部循环可加一个判断来判定是否需要扫描儿子节点,可能是数据问题,该题时间并没有大的变化
转载请注明出处:/article/7053634.html
相关文章推荐
- 北京网赛I题 hiho1391 (树状数组、区间覆盖最大值问题)
- 树状数组写区间最大值
- scu 2057 树状数组 单点更新区间求和问题
- 数据结构----树状数组----修改区间求点值问题
- 【树状数组】【单点修改区间求和】【区间修改单点查询】【单点修改区间最大值查询】
- 树状数组求不带修改前缀最值问题 51NOD 1272 最大距离
- 第k大区间和问题的树状数组实现
- 树状数组求区间最大值
- ARC 068E Snuke Line 区间问题+树状数组
- 区间问题:两道线段树和树状数组的基础练习
- 【第k大区间和问题的树状数组实现】
- 用树状数组解决求区间最值的问题:hdu1754
- 树状数组求区间最大值(树状数组)(复习) - deadshotz - 博客园
- 树状数组解决区间求和问题(模板)
- 【BZOJ1012】【树状数组求区间最值】最大数maxnumber
- 51Nod1463 找朋友(离线处理+树状数组维护区间最大值)
- acm-1003 求一个数组中连续区间和的最大值问题
- 用树状数组解决区间查询问题
- 用树状数组解决"区间和"问题模板(1166)
- 【Leetcod 动态规划】 子数组最大和一类的问题