码迷,mamicode.com
首页 > 其他好文 > 详细

线段树模板

时间:2019-09-05 00:35:52      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:模板   img   传递   求和   end   src   llb   wiki   lazy   

不要当线段树都不会敲的菜鸡了。

线段树所要提供的是查询一个区间 技术图片 内的信息技术图片,并允许修改操作。

 节点数据向上更新

对于区间求和:

void push_up(int rt){
    tree[rt] = tree[rt<<1] + tree[rt<<1|1];
}

对于区间求最值:

void push_up(int rt){
    tree[rt] = max(tree[rt<<1],tree[rt<<1|1]);
}

 节点懒惰标记向下传递

对于区间求和:

void push_down(int rt,int len){
    tree[rt<<1] += lazy[rt]*( len-(len>>1) );
    lazy[rt<<1] += lazy[rt];
    tree[rt<<1|1] += lazy[rt]*(len>>1);
    lazy[rt<<1|1] += lazy[rt];
    lazy[rt]=0;
}

对于区间求最值:

void push_down(int rt){
    tree[rt<<1] += lazy[rt];
    lazy[rt<<1] += lazy[rt];
    tree[rt<<1|1] += lazy[rt];
    lazy[rt<<1|1] += lazy[rt];
    lazy[rt] = 0;
}

建树

void build(int l,int r,int rt){
    lazy[rt] = 0;
    if(l==r){
        tree[rt] = 0;
    }
    int m = l+r>>1;
    build(l,m,rt<<1);
    build(m+1,r,rt<<1|1);
    push_up(rt);
}

更新:

void update(int ql,int qr,int l,int r,int rt,int val){
    if(ql<=l && qr>=r){
        tree[rt] += val*(r-l+1);
        lazy[rt] += val;
        return;
    }
    if(lazy[rt])
        push_down(rt,r-l+1);
    int m = l+r>>1;
    if(ql<=m)
        update(ql,qr,l,m,rt<<1,val);
    if(qr>m)
        update(ql,qr,m+1,r,rt<<1|1,val);
    push_up(rt);
}

查询:

ll query(int ql,int qr,int l,int r,int rt){
    if(ql<=l && qr>=r) return tree[rt];
    if(lazy[rt])
        push_down(rt,r-l+1);
    int m = l+r>>1;
    int res=0;
    if(ql<=m)
        res += query(ql,qr,l,m,rt<<1);
    if(qr>m)
        res += query(ql,qr,m+1,r,rt<<1|1);
    return res;
}

 

线段树模板

标签:模板   img   传递   求和   end   src   llb   wiki   lazy   

原文地址:https://www.cnblogs.com/-Zzz-/p/11462591.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!