数据结构颓废计划I-树状数组复习
2017-01-23 19:23
246 查看
Simple but useful.
对于满足区间加法/减法性质的元素所组成的序列,可以使用树状数组来维护。
Fenwick_Tree[i]为树状数组
lowbit(x)=x&(-x)
lowbit(x)的数学意义在于求出x的二进制表示的从右往左第一个1的位置。在树状数组中,对于Fenwick_Tree[x],它一定等于:
∑i=x−lowbit(x)xAi。
∑i=1yAi−∑i=1x−1Ai=∑i=xyAi
如上的明显的性质,来求给定区间的区间和。
我们将星星按横坐标排序,每次统计高度小于等于当前星星的星星个数,然后再单点修改一下这个高度对应的所有的Fenwick_Tree的值即可, O( N log N ) 左右。
对于满足区间加法/减法性质的元素所组成的序列,可以使用树状数组来维护。
原理
一些约定
Ai 为原序列Fenwick_Tree[i]为树状数组
lowbit
对于一个有符号类型的下标,我们定义:lowbit(x)=x&(-x)
lowbit(x)的数学意义在于求出x的二进制表示的从右往左第一个1的位置。在树状数组中,对于Fenwick_Tree[x],它一定等于:
∑i=x−lowbit(x)xAi。
区间求和
那么对于[1,x]的区间求和问题,我们只需要反复执行上一过程,即可求得。若要求[x,y]的区间和,那么可以由:∑i=1yAi−∑i=1x−1Ai=∑i=xyAi
如上的明显的性质,来求给定区间的区间和。
单点修改
也很明显。这里不讨论。例题
CodeVS1080 线段树练习1
题面
题解
拒绝解释#include "iostream" #include "cstring" using namespace std; int c[1000001]; int N,T; inline int lowbit(int x) { return x&(-x); } int sum(int n) { int Ans=0; while(n>0) { Ans+=c ; n-=lowbit(n); } return Ans; } void change(int i,int x) { while(i<=N) { c[i]=c[i]+x; i=i+lowbit(i); } } int main() { cin >> N; memset(c,0,sizeof(c)); for ( int i=1;i<=N;i++) { cin >> T; change(i,T); } cin >> T; int l,r,op,x,a; for ( int i=1;i<=T;i++) { cin >> op; if(op==1) { cin >> x >> a; change(x,a); } if(op==2) { cin >> l >> r; cout << sum(r) - sum(l-1) << endl; } } return 0; }
URAL1028 STAR
题面
题解
经典老题我们将星星按横坐标排序,每次统计高度小于等于当前星星的星星个数,然后再单点修改一下这个高度对应的所有的Fenwick_Tree的值即可, O( N log N ) 左右。
#include <cstdio> #include <cstring> #include <utility> #include <iostream> #include <algorithm> using namespace std; int N; int a[32002]; int lowbit(int x) { return x^(x&(x-1)); } void update( int i ) { while(i<=32001) { a[i]++; i+=lowbit(i); } return ; } int query( int i ) { int Ans=0; while(i>0) { Ans+=a[i]; i-=lowbit(i); } return Ans; } int in() { char ch=getchar(); int Ans=0; while(ch>'9'||ch<'0') ch=getchar(); while(ch>='0'&&ch<='9') { Ans=Ans*10+ch-'0'; ch=getchar(); } return Ans; } pair < int , int > stars[15001]; int level[15001]; int main() { N=in(); for ( int i=1;i<=N;i++) { stars[i].first=in(); stars[i].second=in(); } sort(stars+1,stars+1+N); memset(a,0,sizeof(a)); memset(level,0,sizeof(level)); for ( int i=1;i<=N;i++) { level[query(stars[i].second+1)]++; update(stars[i].second+1); } for ( int i=0;i<=N-1;i++) printf("%d\n",level[i]); return 0; }
相关文章推荐
- 数据结构颓废计划II-树状数组的推广与应用
- 上半学期数据结构(线段树,树状数组,二叉搜索树,大(小)堆根堆,树堆)复习
- 【数据结构】: 树状数组 (Binary Indexed Trees)
- [树状数组 线段树] BZOJ 3333 排队计划
- 树状数组(数据结构)
- CDOJ 838 母仪天下 树状数组 (2014数据结构专题
- HDU 3966 Aragorn's Story [树链剖分(点权)+树状数组]【数据结构】
- hrbeu基础题解(高级数据结构之树状数组)
- 树状数组求区间最大值(树状数组)(复习) - deadshotz - 博客园
- HDU 4046 Panda [树状数组]【数据结构】
- 洛谷[P3616] 富金森林公园【数据结构】【线段树】【树状数组】
- bzoj 2120 数颜色 树状数组套可持久化数据结构。
- 数据结构:线段树(树状数组、BST、LCA、
- 数据结构复习:栈-Java数组实现
- (POJ 2155)Matrix (复习必看题)经典二维树状数组题目 + 树状数组的论文讲解
- HDU 1542 Stars [树状数组]【数据结构】
- HDU 2689 Sort it [树状数组]【数据结构】
- 【原创】【数据结构】一维树状数组的基本操作(单点修改,区间查询) (HDU1166 敌兵布阵)
- 模板复习计划——线性与半线性数据结构维护
- 数据结构复习——第四章:串、多维数组和广义表