binary indexed tree 二分索引树 树状数组
来源:互联网 发布:淘宝店铺智能版 好用吗 编辑:程序博客网 时间:2024/05/17 01:37
参考:
https://www.byvoid.com/blog/binary-index-tree
http://www.cnblogs.com/sixdaycoder/p/4348360.html
http://blog.csdn.net/liangzhaoyang1/article/details/51365192
1)求Ci
C[i] = A[i-2^k+1] + .........+A[i]。
其中k表示,将i转化为2进制后,从右往左数,0的个数。
C1 = A1
C2 = C1 + A2 = A1 + A2
C3 = A3
C4 = C2 + C3 + A4 = A1 + A2 + A3 + A4
C5 = A5
C6 = C5 + A6 = A5 + A6
C7 = A7
C8 = C4 + C6 + C7 + A8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8
按照C[i] = A[i-2^k+1] + .........+A[i]计算Ci,会产生一些重复计算。如求C8时,C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8。其中A1 + A2 + A3 + A4=C4、 A5 + A6=C6、A7=C7在前面我们已经计算过了,所以我们可以先计算C8的所有子节点,然后将子节点的值累加,这是动态规划的思想,动态规划的核心思想就是避免子问题重复计算。C8的子节点有C4、C6、C7、A8。那么怎么求子节点呢?见下面。
2)求Ci的子节点。
8的二进制形式是1000。对其右移操作,得0100,此时k=2,8-2^2=4,C4。再右移的0010,k=1,8-2^1=6,C6。继续右移0001,k=0,8-2^0 = 7, C7。再加上其本身A8,就得到C8了。再如6,110。右移011,k=0,6-2^0 = 5,C5。再加上A6即为C6。再如7,111。因为其末尾已经没有0了,不用右移,直接是A7。
1)和2)结合求Ci的代码:
vector<int> build_BIT(vector<int> &nums) { vector<int> BIT;//树状数组(二分索引树)int size = nums.size(), temp, s;for (int i = 1; i <= size; ++i){ //构建BITtemp = nums[i-1];s = i;while (s%2!=1){ s = s>>1;temp += BIT[i - lowbit(s) - 1];}BIT.push_back(temp);}return BIT;}
3)求Ci的父节点。
C [i+2^k]即为Ci的父节点,如C4,4=0100,k=2,所以i+2^k = 4+2^2 = 8, 即C8。如C5,5=0101,k=0,所以i+2^k = 5+2^0 = 6, 即C6。
4)怎么求k( 也即怎么求2^k )?
2^k=k&(~k+1),根据补码的性质化简为k&(-k); 这里上面有篇文章里面讲的很细点击打开链接。
5)怎么求前缀和,这才是树状数组要解决的问题。
sum(i) = sum( i - lowbit(i) ) + C[i]
由于C[i]已知,所以sum(i)可以通过递归求解,递归出口为当i = 0时。如sum(8) = sum(8-8) + C8 = C8; sum(6) = sum(6-2^1) + C6 = sum(4-2^2) + C4 +C6 = C4 +C6。
<span style="font-size:18px;">int sum(int p) { int rs=0; while (p) { rs+=C[p]; p-=lowbit(p); } return rs; }</span>6) 更新Ai以及Ci
假如Ai的现在的值为Ai’,则delta = Ai' - Ai。那么改变这个值,会影响哪些C呢?
会改变Ci的父节点、父节点的父节点,具体代码如下:
<span style="font-size:18px;">void modify(int p,int delta) { while (p<=N) { C[p]+=delta; p+=lowbit(p); } }</span>
- binary indexed tree 二分索引树 树状数组
- 树状数组 ( Binary Indexed Tree,BIT,二分索引树 )
- 树状数组 ( Binary Indexed Tree,BIT,二分索引树 )
- 树状数组(Binary Indexed Trees,二分索引树)
- Binary Indexed Tree(二进制索引树、树状数组)
- 树状数组(Binary Indexed Tree)
- 树状数组(Binary Indexed Tree)
- 树状数组(Binary Indexed Tree)
- Binary indexed tree(树状数组)
- 树状数组(Binary Indexed Tree)
- 树状数组 Binary Indexed Tree
- 树状数组(binary indexed tree)
- 树状数组 Binary Indexed Tree
- 树状数组/Binary Indexed Tree/Fenwick Tree
- 树状数组(Binary Indexed Tree)
- POJ 2352 树状数组(Binary Indexed Tree)
- POJ 2481 树状数组(Binary Indexed Tree)
- poj3067 树状数组(Binary Indexed Tree)
- uboot的relocation原理详细分析
- Git可视化极简易教程 — Git GUI使用方法
- 小巧指南针
- OpenCV使用Canny边缘检测器实现图像边缘检测
- 深度学习(一)深度学习的发展历史
- binary indexed tree 二分索引树 树状数组
- Elasticsearch
- Bootstrap框架环境安装和实现图片的圆形
- HDU 5480 Conturbatio
- Google的搜索API的Delphi封装
- mpc-hc win10x64编译x86版本
- SoapUI测试WebSevice接口方法
- iOS程序中的内存分配 栈区堆区全局区
- DAY19_openssl命令行生成服务端证书+建立服务器端