树状数组选讲
来源:互联网 发布:mac录屏如何录制声音 编辑:程序博客网 时间:2024/06/08 08:05
树状数组选讲
树状数组(Binary Indexed Tree(BIT), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构。主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值;经过简单修改可以在log(n)的复杂度下进行范围修改,但是这时只能查询其中一个元素的值。
树状数组,载体还是数组,但是它又有几分线段树的味道,数组本身就记录了某一段的值:
我们看这张图:
c[1]=a[1];
c[2]=a[1]+a[2];
c[3]=a[3];
c[4]=a[1]+a[2]+a[3]+a[4];
c[5]=a[5];
c[6]=a[5]+a[6];
c[7]=a[7];
c[8]=a[1]+a[2]+a[3]+a[4]+a[5]+a[6]+a[7]+a[8];
所谓的求区间和比较快的算法,本质其实就是在第一次操作是已经算好了,最后只要调出来就好了;
我们再来看看树状数组每一位包含数字的个数,不难发现c[n]所含数字个数等于2^k(k是n换做二进制后末尾0的个数);
有个算法可以简单搞定2^k;
int lowbit(int x){return x&(-x);}至于原因吗。。。。。。。。我也不会;
单点更新操作
void update(int x,int num){ while(x<=N) { d[x]+=num; x+=lowbit(x); }}和线段树一样单点更新之后必须要向上更新直到根节点(这里是最后一位N);
比如你修改了a[2]的值,那么向上2,4,8都需要更新;
区间更新操作
这里和线段树也相似但是是需要两次修改后的单点操作
void update(int x,int num){ while(x>0) { d[x]+=num; x-=lowbit(x); }}
将左右区间分别带入就可以了;
例如将x1到x2的数值+1,就update(x1,1),update(x2,-1);
求和操作
int getSum(int x){ int sum=0; while(x>0) { sum+=c[x]; x-=lowbit(x); } return sum;}
求前a[x]的总和,那一定有x个数,每次减去lowbit就是将x二进制中的1去掉一个;
综上树状数组讲完!
0 0
- 树状数组选讲
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 创建springmvc src文件和jsp文件
- 二分查找中term有重复的情况
- 解释型语言与编译型语言的区别
- Mysql压缩包版的安装方法
- AsysnTask&Handler
- 树状数组选讲
- 使用rand5()生成rand7()
- 每个程序员都会的 35 个 jQuery 小技巧
- 一结(13)
- Android-Uiautomator:keyCode快速输入
- 加油,day2
- Error inflating class fragment解决方法
- 进黑马的第一天
- Comparable接口的实现和使用