zoukankan      html  css  js  c++  java
  • 树状数组BIT

    树状数组BIT

    现多用于计算前缀和,区间和,可在O(logN)时间内得到任意前缀和 。并且支持在O(logN)时间内动态单点修改

    树状数组BIT

    C1=A1
    C2=A1+A2
    C3=A3
    C4=A1+A2+A3+A4
    C5=A5
    C6=A5+A6
    C7=A7
    C8=A1+A2+A3+A4+A5+A6+A7+A8
    

    其中 C[i] = A[i - 2k+1] + A[i - 2k+2] + ... + A[i]; //k为i的二进制中从最低位到高位连续零的长度

    例如i = 8(1000)时候,k = 3,可自行验证。

    应用

    针对一个数组A,有A0到An个元素,经过W次修改,每次修改一个元素的值,如何快速求其中任意区间内的和问题?

    如何求和?

    求和

    以7为例,sum求和0-7的计算方法,C的下标数值如何确定,即7开始不断的取lowbit(具体实现见代码lbt)

    实现

    package main
    
    import "fmt"
    
    type Bit struct {
    	BitTree []int
    }
    // 该函数也可写成 x&(-x)
    //函数意义:求x中从最低位开始剔除一个1的数值,例如6(110),剔除最低位1转为4(100)需要减2(10),即lbt(6)=2
    func (b *Bit) lbt(x int) int {
    	return x - (x & (x - 1))
    }
    
    func (b *Bit) Update(x int, v int) {
    	for i := x+1; i < len(b.BitTree); i += b.lbt(i) {
    		b.BitTree[i] += v
    	}
    }
    
    func (b *Bit) GetSum(x int) int {
    	sum := 0
    	for i := x+1; i > 0; i -= b.lbt(i) {
    		sum += b.BitTree[i]
    	}
    	return sum
    }
    
    func Init(a []int) Bit {
    	b := Bit{BitTree: make([]int, len(a)+1)}
    	for i := 0; i < len(a); i++ {
    		b.Update(i, a[i])
    	}
    	return b
    }
    
    func main(){
    	a := []int{1,1,1,1}
    	b := Init(a)
    	fmt.Println(b)
    }
    

    参考

  • 相关阅读:
    Python之路系列:面向对象初级:静态属性、静态方法、类方法
    对象和类
    Python的函数参数传递
    python参数传递:对象的引用
    Python的locals()函数
    Python 异常处理
    Python变量类型的强制转换
    日常问题总结
    高效能人士的七个习惯
    Dojo入门:DOM操作
  • 原文地址:https://www.cnblogs.com/weiweng/p/12604247.html
Copyright © 2011-2022 走看看