树状数组
来源:互联网 发布:淘宝上好看的女装 编辑:程序博客网 时间:2024/06/17 17:55
平常我们经常会遇到一些对数组进行维护查询的操作,比较常见的如:修改某点的值,求某个区间的和。当数据规模不大的时候可以使用朴素方法,但当规模增大后是划不来的。而这两个操作正是树状数组的强项。
树状数组的结构如图所示:
从图中可以看出:c[1] = a[1]
c[2] = a[1] + a[2]
c[3] = a[3]
c[4] = a[1] + a[2] + a[3] + a[4] 等等
树状数组这样的结构,其元素之间的下标就存在一定的对应关系:
int lowbit(int x){ return x&(-x);}
通过lowbit来求出某个结点管辖范围,如果x+=x&(-x),就得到该节点的父节点的下标值,如x=4时,就得到8;而x-=x&(-x),就是得到该节点的管辖区间的下个区间的管辖点,如x=7,代入后6,不断循环到0.修改某点值的函数:
void update(int x,int num){ while(x<=N) { d[x]+=num; x+=lowbit(x); }}
对于一般的数组只需要修改点的值即可,然而树状数组存储的其左右子节点的和,所以需要修改所有该点被管辖的区间。比如a[2]减1,所有2被管辖的点4,8,16都应该减1区间求和函数:
int getSum(int x){ int s=0; while(x>0) { s+=d[x]; x-=lowbit(x); } return s;}
两种情况:
一。每次修改的是一个点,所求的是关于某段区间:向上修改,向下求和
二。每次修改的是一个区间,所求的值关于某个点的:要向下修改,将它后面的区间都加一遍,再向后修改,把不必要的修改区间再减去,用他的父节点记录每个点的染色次数。
void update(int x,int num){ while(x>0) { d[x]+=num; x-=lowbit(x); }}
int getSum(int x){ int s=0; while(x<=N) { s+=d[x]; x+=lowbit(x); } return s;}
练习题:POJ 2352 POJ 2155 POJ 2299 POJ3067 POJ 2352 POJ 3321 POJ2309 POJ1990
http://www.cnblogs.com/Penn000/articles/5758324.html
https://www.topcoder.com/community/data-science/data-science-tutorials/binary-indexed-trees/#prob
0 0
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- Spring MVC实战系列教程(4)--0配置实现spring mvc应用
- C++向量vector 的使用
- Retrofit2 笔记
- 归并排序的实现及利用其求逆序对数
- 如何做到简历中要求的 “要有扎实的 Java 基础
- 树状数组
- int 与 byte 的强制类型转换
- Android Arm Inline Hook
- apache CentOS Permission denied: AH00072
- <Android 开源库> PhotoPicker 从头到脚
- spring mvc实战系列教程(5)--将对象转换为XML输出
- [Leetcode] 115. Distinct Subsequences 解题报告
- IDEA破解
- 一个MySQL表真的最多只能够有24个字段吗?反正我不信