您的位置:首页 > 其它

一二维树状数组模板

2012-12-05 19:34 232 查看
具体参考: http://poj.org/summerschool/1_interval_tree.pdf
一直没有搞清 线段树和树状数组的区别及用途,下面从该讲义中摘录:
树状数组:适合单个元素经常修改而且还反复要求部分的区间的和的情况。上述问题虽然也可以用线段树解决,但是用树状数组来做,编程效率和程序运行效率都更高。上述问题虽然也可以用线段树解决,但是用树状数组来做,编程效率和程序运行效率都更高如果每次要修改的不是单个元素,而是一个区间,那就不能用树状数组了(效率过低)。二维树状数组用于快速求数字子矩阵的和。
线段树:是一棵二叉树,树中的每一个结点表示了一个区间[a,b]。a,b通常是整数。每一个叶子节点表示了一个单位区间。对于每一个非叶结点所表示的结点[a,b],其左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2,b](除法去尾取整)。线段树的深度不超过logL(L是最长区间的长度)。线段树把区间上的任意一条线段都分成不超过2logL条线段。线段树适用于和区间统计有关的问题。比如某些数据可以按区间进行划分,按区间动态进行修改,而且还需要按区间多次进行查询,那么使用线段树可以达到较快查询速度。

树状数组
先dfs()给各节点重新编号,申请空间用临街表存储树。
再可以采用树状数组来修改、求和等操作
先初始化为0,再逐个插入每个节点的权来完成初始化

#define N 10000
int in
;
int Lowbit(int t)
{ return t & ( t ^ ( t - 1 ) ); }

//求前end项和
int Sum(int end)
{
int sum = 0;
while(end > 0)
{
sum += in[end];
end -= Lowbit(end);
}
return sum;
}
//对某个元素进行加法操作:
void plus(int pos , int num)
{
while(pos <= N) //sizeof(in)
{
in[pos] += num;
pos += Lowbit(pos);
}
}
也可以直接模拟建树,应申请空间再进行(不过这个更适合用来做线段树)。
Node *maketree(int l,int r)
{
Node *root= &pMem[nIndex++];
root->l=l;
root->r=r;
root->sum=r-l+1;
if(l==r)return root;
int mid=(l+r)/2;
root->lc=maketree(l,mid);
root->rc=maketree(mid+1,r);
return root;
}
void change(Node *root,int x,int c)
{
root->sum+=c;
if(root->l==root->r)
return;
int mid=(root->l+root->r)/2;
if(mid>=x) change(root->lc,x,c);
else change(root->rc,x,c);
}
int query(Node *root,int l,int r)
{
if(root->l==l&&root->r==r)
return root->sum;
int mid=(root->l+root->r)/2;
if(r<=mid) return query(root->lc,l,r);
else if(l>mid) return query(root->rc,l,r);
else return query(root->lc,l,mid)+query(root->rc,mid+1,r);
}
二维树状数组
下表均是从1开始,num为规模Getsum(r+1,t+1)+Getsum(l,b)-Getsum(r+1,b)-Getsum(l,t+1)为从l+1行到r+1行,b+1列到t+1列的和:

int c[MAXNUM][MAXNUM];
int Lowbit(int m)
{
return m&(-m);
}
int Getsum(int i,int j)
{
int tempj,sum=0;
while(i>0){
tempj = j;
while(tempj>0){
sum += c[i][tempj];
tempj -= Lowbit(tempj);
}
i -= Lowbit(i);
}
return sum;
}
void Inc(int i,int j,int m,int num) //(i,j)增加m
{
int tempj;
while(i<=num){
tempj = j;
while(tempj<=num){
c[i][tempj] += m;
tempj += Lowbit(tempj);
}
i += Lowbit(i);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: