树状数组
来源:互联网 发布:小米4手机只有2g网络 编辑:程序博客网 时间:2024/05/01 06:52
树状数组
树状数组的结构图
为了表示简便,假设现在一个int型为4位,最高位为符号位
int i=3&(-3); 此时i=1,3的二进制为0011,-3的二进制为1101(负数存的是补码)所以0011&1101=1
int j=4&(-4); 此时j=4,理由同上.....
所以计算2^k我们可以用如下代码:
int low(int i){ return i&(-i);}
2,求和操作
求sum[1..k],我们需查找k的二进制表示中1的个数次就能得到最终结果,所以时间复杂度为log(n)。
int sum(int i){ int s=0; while(i>0){ s+=num[i]; i-=low(i); } return s;}
i-=lowbit(i);这一项实际上等价于将当前二进制串中的最后一个1减去,因为数的二进制串中1的个数最多有log(n)个,所以它的时间复杂度为log(n);
然后将这个1舍掉,得到6,二进制表示为0110,右边第一个1出现在第1位上,也就是说要从a[6]开始向前数2个元素(a[6],a[5]),即c[6];
然后舍掉用过的1,得到4,二进制表示为0100,右边第一个1出现在第2位上,也就是说要从a[4]开始向前数4个元素(a[4],a[3],a[2],a[1]),即c[4].
所以s[7]=c[7]+c[6]+c[4];
3,更新操作
在上面的示意图中,假设更改的元素是a[2],那么它影响到得c数组中的元素有c[2],c[4],c[8],我们只需一层一层往上修改就可以了,这个过程的最坏的复杂度也不过O(logN);
void update(int i){ while(i<=n){ num[i]++; i+=low(i); }}
n+=lowbit(n);这一项实际上等价于在二进制串中补0;
以修改a[2]元素为例,需要修改c[2],2的二进制为0010,末尾补0为0100,即c[4]
4的二进制为0100,在末尾补0为1000即c[8]。所以我们需要修改的有c[2],c[4],c[8]
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 张小龙:APP产品经理必须要懂的30条原则
- jQuery简介
- UML图(一) 用例图
- 20060804-Spatial transformations: Defining and applying custom transforms
- 机器学习笔记——SVM
- 树状数组
- SVM入门(十)将SVM用于多类分类
- serialVersionUID作用
- javax.servlet.jsp.JspException: Cannot retrieve definition for form bean 异常问题
- 未来计算的目标
- 平平淡淡才是真
- 2的补码
- 从零单排PAT1004. 成绩排名
- 人为什么要努力(转自新浪微博)