树状数组

半年前自己曾试图理解,半年后还是背代码。

树状数组可用来求逆序数,前缀和,频繁的修改A[i],则C[i]也频繁变,注意下标是从1开始的,而且只能求下标从1到n的和。


令这棵树的结点编号为C1,C2……Cn。令每个结点的值为这棵树的值的总和,那么容易发现:

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

……

C16 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 + A9 + A10 + A11 + A12 + A13 + A14 + A15 + A16

数组c的项数有个特点:即c数组下标用二进制表示时,从有右向左第一个1所在位置代表的数 值,比如c8,1000,从右向左第一个1 的位置为3,2^3=8,所以c8有8项。同时,c8在第三层,即2^k。

 树状数组里有个lowbit函数,就是求2^k。

int lowbit(int x)  

{
return x&(-x);

基本部分

int sum(int x)     //前缀和

{

     int ans=0;

      while(x>0)

    {

     ans+=c[i];

     x-=lowbit(x);

    }

   return  ans;

}

void add(int i,int d)     //第i位置,a[i]修改d,则c也改变

{

    while(i<=n)

   {

     c[i]+=d;

     i+=lowbit(i);

   }

}

适用于区间求和问题,求逆序数

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值