树状数组维护区间最值问题

编程入门 行业动态 更新时间:2024-10-22 02:58:48

<a href=https://www.elefans.com/category/jswz/34/1766397.html style=树状数组维护区间最值问题"/>

树状数组维护区间最值问题

使用树状数组需要理解其具体原理解析链接,记住其维护的区间是 [ x − l o w b i t ( x ) + 1 , x ] ( x ! = 0 ) [x-lowbit(x)+1,x](x!=0) [x−lowbit(x)+1,x](x!=0) l o w b i t ( x ) = x & ( − x ) lowbit(x)=x\&(-x) lowbit(x)=x&(−x)

  1. 维护区间和的时候使用的是前缀和的方式进行维护,依次向上更新
  2. 在维护区间最大值的时候使用的是每个 [ x − l o w b i t ( x ) + 1 , x ] ( x ! = 0 ) [x-lowbit(x)+1,x](x!=0) [x−lowbit(x)+1,x](x!=0)区间的更新,所以在统计 [ l , r ] [l,r] [l,r]区间的最值问题时需要依次统计各个子区间 [ l , . . . ] . . . [ r − l o w b i t ( r ) + 1 , r ] [l,...]...[r-lowbit(r)+1,r] [l,...]...[r−lowbit(r)+1,r]区间的最值。
    例:leetcode-接雨水
    该题可以使用树状数组的方式解决,先找出[0,n]之间的最大值h及其下标index,然后分别向左[0,index]和向右[index,n],计算其区间的最高两个柱子之间的最大值以及能接到的最大雨水。
var bitTree []int
func trap(height []int) int {lent := len(height)bitTree = make([]int, lent+500)index, h := 0, height[0]for i := range height {// fmt.Println(i)if height[i] > h {h = height[i]index = i}add(i, height)}sum := 0//左边for r := index - 1; r >= 0; r-- {for hl := searchMax(0, r, height); height[r] < hl; r-- {sum += (hl - height[r])}}//右边for l := index + 1; l < lent; l++ {for hr := searchMax(l, lent-1, height); height[l] < hr; l++ {sum += (hr - height[l])}}return sum
}func lowbit(x int) int {return x & (-x)
}func max(x, y int) int {if x > y {return x}return y
}func add(x int, height []int) {bitTree[x] = height[x]up := lowbit(x)for i := 1; i < up; i <<= 1 {bitTree[x] = max(bitTree[x], bitTree[x-i])}
}func searchMax(l, r int, height []int) int {ans := height[r]for l < r {ans = max(ans, height[r])for r--; l < r-lowbit(r); r -= lowbit(r) {ans = max(ans, bitTree[r])}}//上面的判断没有将l加入判断ans = max(ans, height[l])return ans
}

更多推荐

树状数组维护区间最值问题

本文发布于:2023-11-16 13:17:02,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1623972.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:树状   数组   区间

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!