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

来源:互联网 发布:mac打开xlsx 不能编辑 编辑:程序博客网 时间:2024/05/16 12:52

二叉索引树(树状数组)

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

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);     }}
0 0
原创粉丝点击