二叉索引树 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 }