数据结构----树状数组----子区间的和
来源:互联网 发布:内链优化 编辑:程序博客网 时间:2024/06/11 14:11
一、几个问题
问题一:已知数组a[],元素个数为n,现在要求a数组中i到j区间内的和(1<=i<=j<=n)
解法1:每次查询就把i到j之间每个元素都加起来。最坏情况O(Qn)(Q为查询次数)
解法2:用前缀和数组sum[k]来记录1到k的和,查询时,就输出sum[j]-sum[i-1]。O(1)
问题二:已知数组a[],元素个数为n,现在有两种操作
1、求a数组中i到j区间内的和(1<=i<=j<=n)
2、将a数组中a[k](1<=k<=n)的值加上d。
解法1:每次查询就把i到j之间每个元素都加起来,每次更改就把a[k]加上d。最坏情况O(Qn)
解法2:用前缀和数组sum[k]来记录1到k的和,查询时,就输出sum[j]-sum[i-1],更改时,就把k到n之间的所有元素都加上d。最坏情况O(Qn)
解法3:树状数组。O(Qlog(n))
树状数组就是在这种背景下产生的。
二、树状数组的概念
利用二进制来分类,每一个数存的数据是存的一个区间,它存的区间大小,取决于它的二进制里权值最低的1权值,
如果感觉听不懂,就来看一下例子吧。
比如说6,转化成二进制位110,权值最低的1就是红色标注的那个1,它的权值是2。
再比如说12,转化成二进制位1100,权值最低的权值就是4。
求它的最低权值有一个简便算法:
int lowbit(int x)
{
return x&-x;
}
接下来就是求和的操作,我们发现1~14之间的和是a[14]+a[12]+a[8],恰好是14对应二进制a[1110],a[1100],a[1000]
(以上的1110、1100、1000位二进制),于是可以发现求和算法:
int getsum(int x)
{
int sum=0;
while(x){
sum+=treearray[x];
x-=lowbit(x);
}
}
然后是修改操作,实际上就是找它的父亲,直到它的父亲大于n为止。
void update(int x,int d)
{
while(x<=n){
treearray[x]+=d;
x+=lowbit(x);
}
}
有了这三个函数,求解上面的问题就容易多了,但是要注意初始化:
for(i=1;i<=n;i++){
scanf("%d",&x);
update(i,x);
}
完整代码:
#include<cstdio>int treearray[1000002],N;int lowbit(int x){ return x&-x;}int getsum(int x){ int sum=0; while(x){ sum+=treearray[x]; x-=lowbit(x); } return sum;}void update(int i,int x){ while(i<=N){ treearray[i]+=x; i+=lowbit(i); }}int main(){ int Q,i,a,b,x; scanf("%d%d",&N,&Q); for(i=1;i<=Q;i++){ scanf("%d%d%d",&x,&a,&b); if(x==0){ update(a,b); } if(x==1){ printf("%d\n",getsum(b)-getsum(a-1)); } }}
- 数据结构----树状数组----子区间的和
- 树状数组 区间和
- 树状数组求序列的区间和
- 数据结构----树状数组----二维区间的修改与查询
- POJ3468 树状数组的区间更新和区间求和
- 树状数组的区间修改和区间查询模板
- 【模板】树状数组的区间加值和区间查询
- 树状数组-区间和-插线问点
- 树状数组求区间和
- 树状数组求区间和
- 数据结构----树状数组----修改区间求点值问题
- 一维树状数组和二维树状数组和三维树状数组的区间更新单点求值
- 第k大区间和问题的树状数组实现
- 树状数组求区间和的一些常见模型
- 【转】树状数组求区间和的一些常见模型
- 【第k大区间和问题的树状数组实现】
- 树状数组求区间和的一些常见模型
- 树状数组求区间和的一些常见模型
- 全局Application(附带ImageLoader默认图片设置)
- 什么是Elasticsearch?
- 在Windows8.1下安装 Teamviewer12 报错
- 【LeetCode】4.Median Of Two Sorted Arrays
- Swift学习记录(二)
- 数据结构----树状数组----子区间的和
- 关于Hibernate QBC语句逻辑或(or)的查询方法
- leetCode之路——Longest Common Prefix
- 深入研究Android Handler机制
- oracle编码格式从utf-8转换为GBK
- Ubuntu字体太小
- 史上最简单清晰的红黑树讲解
- 蓝桥杯 ADV-69 算法提高 质因数
- 感知机及其对偶问题,参考《统计学习方法》