二叉索引树 BIT

BIT         典型题目:http://www.cnblogs.com/bibier/p/4060509.html

说白了    是根据  数的二进制所显示的特征  建成的一棵树    

 

首先明白 lowbit(x)  表示的意思

他表示一个数 最右边的 1 所对应的值

lowbit(x)= x&-x ;  

下面根据lowbit 来建树 

***********建在脑子里*********

 

BIT特点:

首先将每一个节点 进行 编号

1.每一层 节点 的  lowbit  相等

2.一个节点 i 若是左子节点  则  它所对应的父节点的序号为  i - lowbit(i)

                      右                                                   i + lowbit(i)

3.从  完全二叉树的角度 来看     若以一个节点 i 为根节点   则它的 左子树 的序号依次为   i-lowbit(i)+1     i-lowbit(i)+2  ……   i

 

 

c[i]表示空白区域的数的和

c[i] = A( i - lowbit(i) + 1 ) + A( i - lowbit(i) + 2 ) + …… + A( i )  

1 void cc()//求c[i]
2 {
3     for(i=1; i<=nn; i++)
4     {
5         int k=i-lowbit(i);
6         for(j=k+1; j<=i; j++)
7             c[i]+=a[j];
8     }
9 }

 

 

下面来求   前缀和    &&   当其中一个数的值改变 怎样来修改之前计算好的C[],修改哪些。从而才能再求改变后的前缀和

s[i] 表示前缀和

s[i] 向往上爬 s[i] = sum ( c[x] )   ;    x= i - lowbit(i) ;  

 1 int sum_qianzui(int i)//求前缀si的和
 2 //方法:顺着节点i,向左走,边走边往上爬,把沿途经过的ci加起来就是
 3 {
 4     int sum=0;
 5     while(i>0)
 6     {
 7         sum+=c[i];
 8         i=i-lowbit(i);//求前缀的和   向左走 往上爬
 9     }
10     return sum;
11 }

 

 

若某一点改变  需要更改 C[]

从该点  向往上爬 所经过的节点的c[i]都要改变

c[x]=c[x]+changenum ;   x=i + lowbit(i) ; 

 1 void modify(int i,int d)//修改c[i]的数据
 2 //即,当在i节点所对应的数据(a[i])上增加d,改变哪些c[i]
 3 //方法:从c[i],向右走,边走边往上爬,沿途修改所有节点所对应的c[i]   nn表示节点的个数
 4 {
 5     while(i<=nn)
 6     {
 7         c[i]+=d;
 8         i=i+lowbit(i);
 9     }
10 }

 

posted @ 2014-10-20 21:35  bibier  阅读(429)  评论(0编辑  收藏  举报