【Data Structure】树状数组

来源:互联网 发布:怎么关闭手机数据 编辑:程序博客网 时间:2024/05/16 23:34

      对于区间信息进行快速查询是设计许多程序需要实现的功能,树状数组是属于其中比较简单的一种数据结构,其主要功能有查询前缀和与更新数据。


      对于树状的东西,一般又离不开2和二进制,这里我们需要引入一个lowbit的概念。对于每个数组编号,我们可以求出其最低有效位的大小,数学上,数组编号的中心将会成为根(它的lowbit最高)。通过lowbit我们把相对对称的位置取到了同一高度(这里的数学证明暂且不管)。这棵树具有的性质是左节点加上自己的lowbit是父节点编号,而右节点则是减去。下面是求lowbit的代码:

int lowbit(int x){    int result=1;    while(!(1&x))    {        x>>=1;        result<<=1;    }    return result;}

     下面就要说说add操作了,我们如果对某个原始数据加上了d,那么所有包含该数据的区间就都应该加上d。如何操作呢?我们用一个C数组来储存这样一个信息:C[x]表示以x结尾,长度为lowbit(x)区间上的和。这样我们可以发现,每次更新位置为x的原始数据,在lowbit(x)之下的值都不用更新了。也就是从x往上更新就可以了,注意不要超过最大范围:

void add(int x,int d){    while(x<=MAX)    {        c[x]+=d;        x+=lowbit(x);    }}
     查询也并不难,只要把x之前所有和加起来就行了,方法是沿着儿子一步步向下走:

int query(int x){    int res=0;    while(x>0)    {        res+=c[x];        x-=lowbit(x);    }    return res;}

     至此,树状数组的基本功能就全部实现了。



0 0
原创粉丝点击