线段树模板

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值