树状数组学习心得

本文探讨了树状数组基于二进制思想的本质,通过低bit运算快速求和。通过分析树状数组的构造,阐述了如何将a[]数组转换为c[]数组,并解释了区间求和的原理。
摘要由CSDN通过智能技术生成

这里的文章写得不错:http://blog.csdn.net/int64ago/article/details/7429868

这里写图片描述

从这张图片可以看出树状数组是一个二分的思想。那么它的本质是什么呢?其实是二进制数。例如6如果用二进制数来表示6=0110=4+2 , 13=1101=8+4+1 . 因此我们可以用一个c[]数组来表示管辖范围,c[13]=c[8]+c[4]+c[1]. 那么求1~13的和就不用a[1]+a[2]+…a[13]了,而是可以直接c[8]+c[4]+c[1]。

我们可以看出刚才的13是1101有8,4,1构成,倒序来写就是13=1+4+8。我们可以先把1减掉,12=4+8,再把4减掉,8=8,再把8减掉8-8=0.这样一步一步求和运算。对应的1,4,8就是末尾1对应的位置,也就是大牛博客里讲到的Lowbit=x & (-x).这里不赘言。

这里写图片描述
那么如何能把a[]数组转换为c[]数组呢?这里给大家一种构造,就是每个c[i]管辖的范围就是lowbit(i).比如c[6]的管辖范围是2,原因是lowbit(6)=0010,保留最后一个1。那么什么样的子节点对父节点有影响。其实就是它加上它的lowbit.相当于二分(形象的讲是镜像),把它另一边的数加上就是它的父节点。例如4的管辖范围为4,相当于二分镜像的另一边管辖范围,加上自己的节点标号就是父节点的值8。再如10的父节点是12.那么10管辖的范围应该是2,其实也就相当于二分镜像的另一边管辖范围,加上就是父节点的值。

lowbit//-x=取反+1

int lowbit(int x)
{
    return x&(-x);
}

构建父节点c[]

void update(int p,int x)  
{  
    while(p<=n)  
    {  
        c[p]+=x;  
        p+=lowbit(p);  
    }  
} 

区间求和

int sum(int p)   
{  
    int sum=0;  
    while(p>0)  
    {  
        sum+=c[p];  
        p-=lowbit(p);  
    }  
    return sum;  
}   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值