树状数组(Binary Indexed Tree)

树状数组,数组a是原数组,下面是他们的一些关系

数组C就是

C1=a1
C2=a1+a2
C3=a3
C4=a1+a2+a3+a4
C5=a5
……
C8=a1+a2+a3+a4+a5+a6+a7+a8
……
C2^n=a1+a2+….+a2^n

那么树状数组具体怎么定义的呢?思考上面的规律,不难得出结论:

对于序列a,我们设一个数组C定义C[i] = a[i – 2^k + 1] + … + a[i],k为i在二进制下末尾0的个数。
这个C就是树状数组。

2^K的计算很简单:x & -x(网上还有其他版本,如2^k=x and (x xor (x-1)) ,但这个是最简单的了,如果位运算不太理解,记下来就行了)

 

// 树状数组(Binary Indexed Tree)
// 构造函数:
// BIT(int n)    初始化一个最大下标为n的树状数组
// 操作
// modify(int k, int value):将第k个元素修改为value
// sum(k):计算前k个元素的和
// sum(a, b):计算第a个元素到第b个元素的和
// get(k):返回第k个元素的值
class  BIT
{
private:
    
int *C;
    
int size;
    
//用于计算2^k,其中k为x在二进制下末尾0的个数
    
//这样写的理由~~~背下来就行了,反正x & -x很好记
    inline int lowbit(int x)
    
{
        
return (x & -x);
    }

public:
    
//构造函数,初始化一个BIT
    BIT(int n)
        : size(n), C(
new int[n+1])
    
{
        memset(C, 
0sizeof(int)*(n+1));
    }

    
//将第k个元素的值改为val
    
//算法请联系BIT的定义自行思考,或者背下来
    inline void modify(int k, int val)
    
{
        
while (k <= size)
        
{
            C[k] 
+= val;
            k 
+= lowbit(k);
        }

    }

    
//求前k个元素的和,联系定义,很容易明白
    
//背下来也可以
    inline int sum(int k)
    
{
        
if (k == 0)
            
return 0;
        
int t = 0;
        
while (k > 0)
        
{
            t 
+= C[k];
            k 
-= lowbit(k);
        }

        
return t;
    }

    
//返回第a到b个元素的和
    inline int sum(int a, int b)
    
{
        
return sum(b) - sum(a-1);
    }

    
//返回第index个元素
    inline int get(int index)
    
{
        
return sum(index) - sum(index-1);
    }

}
;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值