首页 > 其他 > 详细

线段树模板

时间:2019-09-05 01:23:17      阅读:107      评论:0      收藏:0      [点我收藏+]

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

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

 节点数据向上更新

对于区间求和:

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;
}

 

线段树模板

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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!