线段树模板

Posted -zzz-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树模板相关的知识,希望对你有一定的参考价值。

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

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

 节点数据向上更新

对于区间求和:

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;

 

以上是关于线段树模板的主要内容,如果未能解决你的问题,请参考以下文章

线段树 (区间覆盖模板)

[模板] 线段树合并

权值线段树套序列线段树

洛谷P3372线段树模板1——线段树

[模板]线段树2-线段树

P6012 模板线段树分裂