线段树模板


//线段树模板(单点更新)
#define Mid ((l+r)>>1)
#define lson rt<<1,l,Mid
#define rson rt<<1|1,Mid+1,r
const int maxn = 100010;
int sum[maxn<<2];

void build(int rt,int l,int r)
{
    if(l==r){
        scanf("%d",&sum[rt]);
    }else{
        build(lson);
        build(rson);
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
}

void update(int rt,int l,int r,int pos,int num)		//修改pos位值为num
{
    if(l == r && r == pos){     
        sum[rt] += num;
    }else{
        if( pos <= Mid)
            update(lson,pos,num);
        else        
            update(rson,pos,num);
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
}

int query(int rt,int l,int r,int L,int R)			//查询[L,R]
{
    if(L <= l && r <= R){
        return sum[rt];
    }else{
        int tmp = 0;
        if( L <= Mid)
            tmp += query(lson,L,R);
        if( R > Mid)
            tmp += query(rson,L,R);
        return tmp;
    }
}


调用例子:
int main()
{
    int n,L,R;
    while(scanf("%d",&n)!=EOF){
        build(1,1,n);
        scanf("%d%d",&L,&R);
            update(1,1,n,L,R);
        scanf("%d%d",&L,&R);
            printf("%d\n", query(1,1,n,L,R));       //修改L处值为R
    }
    return 0;
}



//线段树模板(区间更新)
#define Mid ((l+r)>>1)
#define lson rt<<1,l,Mid
#define rson rt<<1|1,Mid+1,r
const int maxn = 100010;
int sum[maxn<<2],add[maxn<<2];

void build(int rt,int l,int r)
{
    add[rt] = 0;
    if(l == r){
        scanf("%d",&sum[rt]);                       //省个数组
    }else{
        build(lson);
        build(rson);
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
}

void pushDown(int rt,int len)
{
    add[rt<<1] = add[rt<<1|1] = add[rt];
    sum[rt<<1] = (len-(len>>1))*add[rt];
    sum[rt<<1|1] = (len>>1)*add[rt];
    add[rt] = 0;
}

void update(int rt,int l,int r,int L,int R,int z)    //更新[L,R]为z
{
    if(L <= l && r <= R){
        add[rt] = z;
        sum[rt] = (r-l+1)*z;
    }else{
        if(add[rt])
            pushDown(rt,r-l+1);
        if(L <= Mid)
            update(lson,L,R,z);
        if(R > Mid)
            update(rson,L,R,z);
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
}

int query(int rt,int l,int r,int L,int R)           //查询[L,R],调用:(1,1,n,L,R)
{
    if(L <= l && r <= R){
        return sum[rt];
    }else{
        if(add[rt])
            pushDown(rt,r-l+1);
        int t = 0;
        if(L <= Mid)
            t += query(lson,L,R);
        if(R > Mid)
            t += query(rson,L,R);
        return t;
    }
}

调用例子:

int main()
{
    int L,R,z;
    while(scanf("%d%d",&n,&m)!=EOF){
        build(1,1,n);
        while(m--){
            scanf("%*c%c",&op);
            if(op=='C'){
                scanf("%d%d%d",&L,&R,&z);
                update(1,1,n,L,R,z);
            }else{
                scanf("%d%d",&L,&R);
                printf("%d\n",query(1,1,n,L,R));
            }
        }
    }
}


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值