区间信息的维护和查询系列算法-树状数组

二叉索引树(树状数组)

树状数组的学习是看的这篇博文,从树状数组的作用, 原理和实现来讲解。仔细看看会有收获,下面是我自己的对树状数组的体会。

1.树状数组的应用。
当我们求解一个动态连续和查询问题的时候,树状数组就派上了用场, 它是一种数据结构,进行连续和查询时的时间复杂度为O(logn)。
树状数组经典图

从上图中我们可以发现一个规律,由a数组和c数组组成,
c[1]=a[1];
c[2]=a[1]+a[2];
c[3]=a[3];
c[4]=a[1]+a[2]+a[3]+a[4];
c[5]=a[5];
c[6]=a[5]+a[6];
c[7]=a[7];
c[8]=a[1]+a[2]+a[3]+a[4]+a[5]+a[6]+a[7]+a[8];

相信大家也都看出规律来了,要根据i的奇偶分两种情况。
当i为奇数时,c[i]=a[i];
当i为偶数时,要看i的因子中最多有2的多少次幂,例如4=2^2,6的因子为2=2^1,8=2^3;所有4,6,8分别由4,2,8个a数组元素组成。且都是由i向前数相应的数。例如c[6]=a[5]+a[6];

(一)公式
ci=a(i-a^k+1)+………+an(其中 k 为 n 的二进制表示中从右往左数的 0 的个数,数到1就停止,当为奇数的时候低位总是1,所以k=0)。偶数可以自己动手算一下。

于是就有了树状数组的一个重要的因素。

int lowbit(int x)
{
     return x&(-x);    
}

在这里解释下该算法的含义,(来自白书)我们知道在计算机中,整数都是以其补码的形式表示的,因此-x实际上是x按位取反再加1的效果,
38288=1001010110010000
-38288=0110101001110000
与运算之后,前面的全变成0,之后的lowbit位不变,返回2^k;

求和
注意n-lowbit(n)的含义

int Sum(int n)
{
    int sum=0;
    while(n>0)
    {
         sum+=c[n];
         n=n-lowbit(n);
    }    
    return sum;
}

动态修改

void change(int i,int x)
{
     while(i<=n)
     {
          c[i]=c[i]+x;
          i=i+lowbit(i);
     }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值