数据结构颓废计划II-树状数组的推广与应用
来源:互联网 发布:mac版adobe flash cs6 编辑:程序博客网 时间:2024/05/29 07:36
二维树状数组
基础知识
若将树状数组与前缀和对应起来,那么二维树状数组就可以与二维前缀和对应起来。此时循环不适合以while的形式出现,而适合以for的嵌套的形式出现。单点修改与区间查询的顺序还是一样。
模板
int lowbit ( int x ) { return x&(-x); }
void update( int x , int y , int delta ) { for ( int i=x;i<=N;i+=lowbit(i)) for ( int j=y;j<=N;j+=lowbit(j)) Fenwick_Tree[i][j]+=delta; }
int query( int x , int y ) { int Ans=0; for ( int i=x;i>0;i-=lowbit(i)) for ( int j=y;j>0;j-=lowbit(j)) Ans+=Fenwick_Tree[i][j]; return Ans; }
应用
POJ1195 IOI2001 Mobile Phones
裸题。
代码
#include <stdio.h>#include <string.h>int Fenwick_tree[1050][1050],N=5;int lowbit ( int x ) { return x&(-x); }void update( int x , int y , int delta) { for ( int i=x;i<=N;i+=lowbit(i)) for ( int j=y;j<=N;j+=lowbit(j)) Fenwick_tree[i][j]+=delta; }int query( int x , int y ) { int Ans=0; for ( int i=x;i>0;i-=lowbit(i)) for ( int j=y;j>0;j-=lowbit(j)) Ans+=Fenwick_tree[i][j]; return Ans; }int main() { int Oper,x,y,a,x1,x2,y1,y2; memset(Fenwick_tree,0,sizeof(Fenwick_tree)); while(scanf("%d",&Oper)!=EOF) { if(Oper==0) { scanf("%d",&N); N++; } else if(Oper==1) { scanf("%d%d%d",&x,&y,&a); x++,y++; update(x,y,a); } else if(Oper==2) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); x2++,y2++; printf("%d\n",query(x2,y2)+query(x1,y1)-query(x1,y2)-query(x2,y1)); } else if(Oper==3) break; } return 0; }
POJ2155 Matrix 楼天城男人八题
做法
TODO
代码
TODO
区间修改
做法
维护一个增量数组
用递推可以维护
例题
CodeVS1082 线段树练习3
题解
不解释
代码
#include <stdio.h>long long Fenwick_Tree1[200001],Fenwick_Tree2[200001],A[200001],N;long long lowbit(long long x) { return x&(-x); }void update( long long i , long long x , long long* target ) { while(i<=N) { target[i]+=x; i+=lowbit(i); } return ; }long long query ( long long i , long long *target) { long long Ans=0; while(i>0) { Ans+=target[i]; i-=lowbit(i); } return Ans; }long long in() { long long Ans=0; char ch=getchar(); char bi=1; while(ch>'9'||ch<'0') { ch=getchar(); if(ch=='-') bi=-1;} while(ch>='0'&&ch<='9'){ Ans=Ans*10+ch-'0'; ch=getchar(); } return bi*Ans; }int main() { N=in(); for ( int i=1;i<=N;i++) { A[i]=in(); A[i]+=A[i-1]; } long long Q=in(),op,L,R,x; for ( int i=1;i<=Q;i++) { op=in(); if(op==1) { L=in(),R=in(),x=in(); update(L,x,Fenwick_Tree1); update(R+1,-x,Fenwick_Tree1); update(L,x*L,Fenwick_Tree2); update(R+1,-x*(R+1),Fenwick_Tree2); } else { L=in(),R=in(); L=A[L-1]+L*query(L-1,Fenwick_Tree1)-query(L-1,Fenwick_Tree2); R=A[R]+(R+1)*query(R,Fenwick_Tree1)-query(R,Fenwick_Tree2); printf("%lld\n",R-L); } } }
杂项
树状数组求逆序对
做法其实和I中的Star一题相似,先离散化,然后过程几乎相同,但是需要修改计数的对象。这里不写了。
树状数组求RMQ
TODO
树状数组的作用,局限和推广
作用
以常数较低,空间浪费较少的方式,处理区间问题。
局限
必须在区间某运算与其逆运算均成立的情况下使用。
推广:ST表
ST表思想与树状数组相同。但它比树状数组存储的信息多一点,如果我们将树状数组前后倒置,即得到ST表的一部分。我们即不需要满足区间运算性质,而直接运用合并的方法来处理这个问题。容易证明,其空间复杂度
例题:SHTSC 200X CLIMB
解法
一道需要注意细节的水题,用线段树和树状数组可能会被卡常。
代码
#include <math.h>#include <stdio.h>#include <string.h>using namespace std;short RMQ[5000001][30];int N,Q,l,r;short max(short a,short b) { return a>b?a:b;}short query( int l , int r ) { short x=(short)(log(r-l+1)/log(2)); return max(RMQ[l][x],RMQ[r+1-(1<<x)][x]);}int main() { freopen("climb.in","r",stdin); freopen("climb.out","w",stdout); memset(RMQ,0,sizeof(RMQ)); scanf("%d",&N); for ( int i=1;i<=N+1;i++) scanf("%d",&RMQ[i][0]); for ( int j=1;j<=log(N+1)/log(2);j++) for ( int i=1;i+(1<<j)-1<=N+1;i++) RMQ[i][j]=max(RMQ[i][j-1],RMQ[i+(1<<(j-1))][j-1]); scanf("%d",&Q); for ( int i=1;i<=Q;i++) { scanf("%d%d",&l,&r); printf("%d\n",query(l+1,r+1)); } return 0; }
0 0
- 数据结构颓废计划II-树状数组的推广与应用
- 数据结构颓废计划I-树状数组复习
- 数据结构颓废计划VI-堆
- 数据结构颓废计划III-基础线段树
- 数据结构颓废计划V-ZKW线段树
- 树状数组 推广
- 树状数组的应用
- 树状数组的应用
- 数据结构----树状数组----二维区间的修改与查询
- poj2481-树状数组的应用
- HDU3874树状数组的应用
- 树状数组的应用系列
- 【树状数组】树状数组及扩展与应用
- 数据结构与算法系列-线性表-数组(线性表的推广)
- hdu——1166(数据结构之树状数组的简单应用)
- 数据结构----树状数组----子区间的和
- 数据结构之树状数组
- 数据结构之树状数组
- Android 性能优化 降低cpu和内存消耗之while循环
- Python中小错误 之 object() takes no parameters
- [转]使用$controllerProvider按需加载controller
- 【G】开源的分布式部署解决方案(一)_0
- 三、用scikit-learn求解一元线性回归问题
- 数据结构颓废计划II-树状数组的推广与应用
- P1338 末日的传说
- JAVA源码分析Collection之ArrayList
- windons下安装gvim8.0支持python3.5
- Spring学习笔记-Spring Cache
- 四、用scikit-learn求解多元线性回归问题
- acpi 自动注册platform_device
- 五、用matplotlib绘制精美的图表
- 编程珠玑: 12章 取样问题 12.3设计空间,程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内m个随机整数的有序列表,不允许重复。 -------解题总结