线段树

参考博客线段树详解

 线段树入门&lazy思想

模板:

#define Mid ((l+r)>>1)          //注意括号
#define lson rt<<1,l,Mid    //左结点
#define rson rt<<1|1,Mid+1,r    //右结点
常用宏定义
//线段树模板(单点更新)
#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;
    }
}
单点更新
//线段树模板(区间更新)
#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;
    }
}
区间更新
    //建树 
    Build(1,n,1); 
    //点修改
    Update(L,C,1,n,1);
    //区间修改 
    Update(L,R,C,1,n,1);
    //区间查询 
    int ANS=Query(L,R,1,n,1);
函数调用 
原文地址:https://www.cnblogs.com/young-children/p/11645181.html