ACM_模板_线段树

来源:互联网 发布:python 绘制中国地图 编辑:程序博客网 时间:2024/05/16 15:31

线段树,作为一项统计神学,和树状数组一样也是一项需要掌握的杀手锏。

线段树的代码分为三个模块:建树·更改·查询。

1.建树:

建树的过程是通过不断的分成左子树和右子树,一层一层的叠上去。采用的是递归的思想。

void Build(int left,int right,int rt){    if(left == right)    {         scanf("%d",&tree[rt]);         return;    }    int mid = (left+right)>>1;    Build(left,mid,rt<<1);    Build(mid+1,right,(rt<<1)+1);    tree[rt]=max(tree[rt<<1],tree[(rt<<1)+1]);}

2.更改:

更改的过程是从树的最下面改的,所以在改了最下面后,我们还要一层一层的叠上去。

void Update(int p,int q,int left,int right,int rt){if(left == right){    tree[rt]=q;    return;}int mid = (left+right)>>1;if(p <= mid)Update(p,q,left,mid,rt<<1);else Update(p,q,mid+1,right,(rt<<1)+1);tree[rt] = max(tree[rt<<1],tree[(rt<<1)+1]);}

3.查询:

查询才是整个线段树的核心,是成就此神学统计方法的绝学^^~,通过判断线段的左右在当前查询的线段中的位置来进行查询。

int Query(int L,int R,int left,int right,int rt){    if(L<=left && right<=R)        return tree[rt];    int mid = (right+left)>>1;    int ret=0;    if(L<=mid)        ret=max(ret,Query(L,R,left,mid,rt<<1));    if(R>mid)        ret=max(ret,Query(L,R,mid+1,right,(rt<<1)+1));    return ret;}

查询功能还可以查询一段里面的所有子树的和

int Query(int left,int right,int i)//查询{int mid;if(b[i].left==left && b[i].right==right) return b[i].sum;mid = (b[i].left+b[i].right)/2;if(right <= mid) return Query(left,right,2*i);//在左子树else if(left > mid) return Query(left,right,2*i+1);//在右子树else return Query(left,mid,2*i)+Query(mid+1,right,2*i+1);//否则在中间}




0 0
原创粉丝点击