树状数组
来源:互联网 发布:蜂窝数据没有app选项 编辑:程序博客网 时间:2024/06/06 01:11
树状数组是个很简单就能学会的东西,我以前学会了线段树就不想去学树状数组,今天无聊学习了一下,发现好简单,耗时不到1小时。
如图为树状数组存储结构。
首先是用A数组读入所有的值,然后用C数组保存树状数组的值。
C[m]=sum(a[m-pow(2, k)+1],...a[m])=(m所管辖范围之和)。
我们看看上面这个公式,C数组所存的值就是其各自管辖区域的所有值和。
我们看看上面这个公式,C数组所存的值就是其各自管辖区域的所有值和。
m-pow(2, k)+1就是管辖区域的第一个值,m就是最后一个。
那么管辖区域就是pow(2, k),k是m二进制末尾0的个数的值。
pow(2, k)可以用一个位运算求得:
m^(m - 1)就会得到m二进制后缀0的个数k,其结果为k+1个1组成的二进制数。int lowbit(int m){return m & (m ^ (m - 1));}
然后再&m,其结果即为将k+1个1组成的二进制数的后k个1置0,也就是2的k次方。
接下来我们说说关于求和,对于区间1到m之间的和。
代码如下:
对于上面代码,s每次都会加上当前m值所管辖范围的和,而每次相加后,m都要减去其管辖范围的大小。int sum(int m){int s = 0;while (m > 0){s += c[m];m -= lowbit(m);}return s;}
要求区间4到7的和,那就是sum(7) - sum(3);
再接下来是修改区间的范围的值。
代码如下:
void update(int i, int x){while (i <= n){c[i] += x;i += lowbit(i);}}
循环将区间里的每个 i 传入即可。
0 0
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 2013杭州邀请赛——我在浙工大屏峰校区
- priority_queue用法
- 我的ACM算法旅程
- 面向对象的一些知识
- 容斥原理
- 树状数组
- n!中包含了几个因子x
- ios block 实现函数回调
- 我就是喜欢敲trie树
- POJ3270 置换群
- 2013亚洲赛长春赛区regional
- NOJ题库——来自Hungar
- linux下《UNIX环境高级编程》(apue2)源码编译出错的处理方法
- 【Cocos2d-x】数据加密解密