树状数组学习心得
来源:互联网 发布:网络三大邪书十大污书 编辑:程序博客网 时间:2024/06/18 04:32
这里的文章写得不错: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; }
0 0
- 树状数组学习心得
- 树状数组学习心得
- 树状数组学习心得
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- POJ1017Packets
- Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for ^
- HTML5 article元素
- 兜转数年,老跳成了卖过软件开过店写过APP的电脑老师
- JavaScript 使用浏览器开发者工具
- 树状数组学习心得
- BZOJ1029: [JSOI2007]建筑抢修
- 单例模式(Singleton-Pattern)
- 本机idea远程调试flume
- 深度学习(16):Induction
- 448.Find All Numbers Disappeared in an Array
- 内聚耦合分类
- linux date 命令详解
- win7下DOS命令无法使用的解决办法