树状数组模板
来源:互联网 发布:雷迪克数据 编辑:程序博客网 时间:2024/06/07 03:48
树状数组
树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)是一个查询和修改复杂度都为log(n)的数据结构。主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值;经过简单修改可以在log(n)的复杂度下进行范围修改,但是这时只能查询其中一个元素的值(如果加入多个辅助数组则可以实现区间修改与区间查询)。
这种数据结构(算法)并没有C++和Java的库支持,需要自己手动实现。在Competitive Programming的竞赛中被广泛的使用。树状数组和线段树很像,但能用树状数组解决的问题,基本上都能用线段树解决,而线段树能解决的树状数组不一定能解决。相比较而言,树状数组效率要高很多。
假设数组a[1..n],那么查询a[1]+…+a[n]的时间是log级别的,而且是一个在线的数据结构,支持随时修改某个元素的值,复杂度也为log级别。
来观察这个图:
令这棵树的结点编号为C1,C2…Cn。令每个结点的值为这棵树的值的总和,那么容易发现:
C1 = A1
C2 = A1 + A2
C3 = A3
C4 = A1 + A2 + A3 + A4
C5 = A5
C6 = A5 + A6
C7 = A7
C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8
…
C16 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 + A9 + A10 + A11 + A12 + A13 + A14 + A15 + A16
这里有一个有趣的性质:
设节点编号为x,那么这个节点管辖的区间为2^k(其中k为x二进制末尾0的个数)个元素。因为这个区间最后一个元素必然为Ax,
所以很明显:Cn = A(n – 2^k + 1) + … + An
#include<iostream>using namespace std;int n,m,i,num[100001],t[200001],l,r;//num:原数组;t:树状数组 int lowbit(int x){ return x&(-x);}void change(int x,int p)//将第x个数加p { while(x<=n) { t[x]+=p; x+=lowbit(x); } return;}int sum(int k)//前k个数的和 { int ans=0; while(k>0) { ans+=t[k]; k-=lowbit(k); } return ans;}int ask(int l,int r)//求l-r区间和 { return sum(r)-sum(l-1); }int main(){ cin>>n>>m; for(i=1;i<=n;i++) { cin>>num[i]; change(i,num[i]); } for(i=1;i<=m;i++) { cin>>l>>r; cout<<ask(l,r)<<endl; } return 0;}
- 树状数组【模板】
- 树状数组模板
- 树状数组 模板
- 树状数组模板
- 树状数组模板
- 树状数组-模板
- 树状数组模板
- 树状数组模板
- 树状数组模板
- 树状数组--模板
- 树状数组模板
- 模板 树状数组
- 模板,树状数组
- 树状数组(模板)
- 树状数组模板
- 树状数组的模板;
- 树状数组 (模板)
- 树状数组BIT 模板
- 使用IE浏览器“下载”网页中没有下载地址的视频
- iOS Hacker Keychain相关The executable was signed with invalid entitlements
- 一个开发对运维的一点反思
- centos 使用 systemctl 使 docker 容器(container)开机启动
- 登陆页面
- 树状数组模板
- 从零开始学习Kinect编程(一) 4.20
- uva481(打印LIS路径)
- Educational Codeforces Round 19 E. Array Queries
- CodeForces 623 B.Array GCD(数论+dp)
- VS2008工程向Linux移植
- 训练营第六天作业
- bash位置参数变量
- unix高级环境编程.第一章习题答案