您的位置:首页 > 其它

线段树模板

2016-08-13 10:23 253 查看
int date[MAXN];//存放输入数据

struct Node

{

    int left,right;

    int sum;
}tree[MAXN*4];//定义数的结点

//建树

void Build(int k,int l,int r)

{

    tree[k].left=l;

    tree[k].right=r;

    if(tree[k].left==tree[k].right)

    {

        tree[k].sum=date[tree[k].left];

        return;

    }

    else

    {

            int mid=(l+r)/2;

            Build(k<<1,l,mid);

            Build((k<<1)+1,mid+1,r);

            tree[k].sum=tree[k<<1].sum+tree[(k<<1)+1].sum;

    }
}

//查询功能

int query(int k,int l,int r)//k一般为1,   查询l到r的和

{

    if(tree[k].left==l&&tree[k].right==r)

          return tree[k].sum;

    else

    {

        int mid =(tree[k].left+tree[k].right)/2;

        if(l>mid)//完全在右子树

            return query((k<<1)+1,l,r);

        else if(r<=mid)//完全在左子树

            return query(k<<1,l,r);

        else//左右子树都有

            return query(k<<1,l,mid)+query((k<<1)+1,mid+1,r);

    }
}

//单点更新

void Update(int k,int l,int r,int pos,int delta)//k一般为1,更新在l到r的范围内   date【pos】 处加上delta(变量,增量)

{

    if(tree[k].left>pos||tree[k].right<pos)//如果pos不在当前tree【k】的范围内  就直接返回

        return ;

    if(tree[k].left==tree[k].right)//相当于==pos

    {

        tree[k].sum+=delta;

        return ;

    }
    int mid=(tree[k].left+tree[k].right)/2;

    if(l>mid) // l > mid说明pos一定落在右子树范围内

        Update((k<<1)+1,l,r,pos,delta);

    else if(r<=mid)/// r <= mid说明pos一定落在左子树范围内

        Update(k<<1,l,r,pos,delta);

    else// 若l,r在mid两端,则将区间[l,r]分成[l,mid]和[mid+1,r]递归查找

    {

        Update(k<<1,l,mid,pos,delta);

        Update((k<<1)+1,mid+1,r,pos,delta);

    }

    tree[k].sum=tree[k<<1].sum+tree[(k<<1)+1].sum;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: