树状数组入门笔记
来源:互联网 发布:一句话介绍自己 java 编辑:程序博客网 时间:2024/06/06 08:39
网上有很多关于树状数组的博客,有很多也讲得很好。
但我感觉对于树状数组,自己始终只能去套模板,所以打算自己写一篇博客,梳理梳理树状数组的用法。
首先上一篇博客。树状数组入门
感觉很无敌,入门足够用了。
我们用C[] 数组来储存树状数组中的信息。
1=(001) C[1]=A[1];
2=(010) C[2]=A[1]+A[2];
3=(011) C[3]=A[3];
4=(100) C[4]=A[1]+A[2]+A[3]+A[4];
5=(101) C[5]=A[5];
6=(110) C[6]=A[5]+A[6];
7=(111) C[7]=A[7];
8=(1000) C[8]=A[1]+A[2]+A[3]+A[4]+A[5]+A[6]+A[7]+A[8];
找规律发现,C[i]所代表的元素是原数组中以i结尾的,连续的,2^k 个元素。(这里的k其实可以代表这个元素在树中的高度)
所以可以轻松发现这其中有前缀和的性质。
例如前3(11)个元素 就是C[3(11)]+C[2(10)]
再例如前6(110)个元素 就是C[110]+C[100]
每次去除一个末尾1 直至下标为0。
那么 利用前缀和的思想,我们就可以很轻松的求出任意连续区间内的数字的和。
再然后就是修改操作。 每修改一个元素,我们都要修改与之相关的所有元素。
由于树的最高高度为logn层,每层只修改一个元素,所以最多修改logn个元素,因此修改操作的复杂度为O(logn)而普通的前缀和修改一个元素需要O(n)的时间。
同理,对于查询操作,其复杂度也为O(logn).
树状数组模板如下
int lowbit(int x){return x&(-x);}void add(int i,int val){ for(;i<=n;i+=lowbit(i)) bit[i]+=val;}int query(int i){ int ans=0; for(;i>=1;i-=lowbit(i)) ans+=bit[i]; return ans;}
然后树状数组很容易推广到二维,相当于n个树状树状数组加起来。
const int MAX=2555;int seed=6666;int n,m,q;int lowbit(int x){ return x&(-x);}int c[MAX][MAX];int sum(int i,int j){ int tempj,sums=0; while(i>0) { tempj=j; while(tempj>0) { sums+=c[i][tempj]; tempj-=lowbit(tempj); } i-=lowbit(i); } return sums;}void update(int x,int y,long long num){ for(int i=x;i<=n;i+=lowbit(i)) { for(int j=y;j<=m;j+=lowbit(j)) { c[i][j]+=num; } }}
未完待续。
- 树状数组入门笔记
- 树状数组 入门
- poj2352树状数组入门
- 树状数组入门
- 树状数组入门
- 树状数组简单入门
- 树状数组入门理解
- 树状数组知识入门
- 树状数组入门
- 树状数组入门
- [笔记] 树状数组
- 树状数组学习笔记
- 树状数组学习笔记
- 学习笔记----树状数组
- 树状数组学习笔记
- 树状数组拓展笔记
- 【数据结构】树状数组笔记
- 学习笔记:树状数组
- GKCheckerboardNoiseSource
- iOS查看日志利器 —— socat
- mac环境下创建bash_profile文件并写入内容
- 2017京东笔试--通过考试
- Sublime Text2/3怎样在Ubuntu中配置CTags插件
- 树状数组入门笔记
- Destoon b2b 6.0 PC端浏览器直接访问手机端地址的修改方法
- Struts类型转换器
- 微信小程序开发(4)---页面切换
- 解决"学习python-flask教程,下载源码运行的时候出现:TypeError: 'bool' object is not callable 错误代码:"
- String,StringBuffer,StringBuilder 三者的区别
- 【2】Vim文档编辑
- Eclipse如何快速修改工程名及包名
- php的foreach的方法生成三级目录