线段树

本人真的是金鱼脑了。。。学过的算法立马忘。。真的是。。

今天复习一下线段树。


#define maxn 200005
int sum[maxn<<2],add[maxn<<2];
int A[maxn],n;
void pushup(int rt){
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l,int r,int rt){
    if(l==r){
        sum[rt]=A[l];
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,rt<<1);
    bulid(m+1,r,rt<<1|1);
    pushup(rt);
}
void update(int L,int c,int l,int r,int rt){//rt表示当前节点,A[L]+=c
    if(l==r){
        sum[rt]+=c;
        return ;
    }
    int m=(l+r)>>1;
    if(L<=m) update(L,c,l,m,rt<<1);
    if(R>m) update(L,c,m+1,r,rt<<1|1);
    pushup(rt);
}
void pushdown(int rt,int ln,int rn){
    if(add(rt)){
        add[rt<<1]+=add[rt];
        add[rt<<1|1]+=add[rt];
        sum[rt<<1]+=add[rt]*ln;
        sum[rt<<1|1]+=add[rt]*rn;
        add[rt]=0;
    }
}
void Update(int L,int R,int c,int l,int r,int rt){//区间修改
    if(L<=l&&r<=R){
        sum[rt]+=c*(r-l+1);
        add[rt]+=c;//标记
        return ;
    }
    int m=(l+r)>>1;
    pushdown(rt,m-l+1,r-m);
    if(L<=m)  Update(L,R,c,l,m,rt<<1);
    if(R>m) Update(L,R,c,m+1,r,rt<<1|1);
    pushup(rt);
}
int query(int L,int R,int l,int r,int rt){//L,R为操作区间
    if(L<=l&&r<=R){
        return sum[rt];
    }
    int m=(l+r)>>1;
    pushdown(rt,m-l+1,r-m);
    int ans=0;
    if(L<=m) ans+=query(L,R,l,m,rt<<1);
    if(R>m) ans+=query(L,R,m+1,r,rt<<1|1);
    return ans;
}

猜你喜欢

转载自blog.csdn.net/sinat_38857184/article/details/79943797