树状数组

来源:互联网 发布:周润发 知乎 编辑:程序博客网 时间:2024/06/06 07:01
定义:
给定数组A,我们设一个数组C满足  (下标都是从1开始)
C[i] = 从A[i]开始的左边k个数的和
其中,k为 i 在二进制下末尾0的个数!  即 k = i & - i 
则我们称C为树状数组。


方法:

void add(int i,int num)  // 建表{    while(i<=n)    {        tree[i]+=num;        i += i & -i ;    }}
int sum(int k)      // 求1~k的区间和  想求a到b的区间和,就sum(b)-sum(a){    int ans=0;    while(k)    {        ans+=tree[k];        k -= k & -k;  // 或者 k &= k - 1 ;    }    return ans;}




使用:经常用来标记状态,即调用add( i ,1 ) 或 add( i ,-1 )就可以在lg n的时间内统计出前面已被标记过多少数
注意:当有数据是0的时候,可以全部数据+1可以避免对0下标操作



hdu 1541 Stars
树状数组经典入门题。

poj 2155 Matrix
二维树状数组经典题   (跟一维是一样滴)


1 0