• 线段树lazy模板 luogu3372


    线段树写得很少,这么基本的算法还是要会的……

    #include<bits/stdc++.h>
    using namespace std;
    inline long long read() {
        long long x = 0, f = 1; char ch = getchar();
        while (ch<'0' || ch>'9') { if (ch == '-') f = -1;ch = getchar(); }
        while (ch >= '0'&&ch <= '9') { x = x * 10 + ch - '0';ch = getchar(); }
        return x*f;
    }
    const int maxn = 131071;
    int n,m,op,_l,_r,k;
    struct NODE{
        int l,r;
        long long lazy,val;
    }node[maxn<<2];
    void pushup(int rt){
        node[rt].val = node[rt<<1].val+node[rt<<1|1].val;
    }
    void pushdown(int rt){
        if(!node[rt].lazy) return ;
        int mid = node[rt].l+node[rt].r >>1;
        node[rt<<1].lazy += node[rt].lazy;
        node[rt<<1|1].lazy += node[rt].lazy;
        node[rt<<1].val += node[rt].lazy*(mid-node[rt].l+1);
        node[rt<<1|1].val += node[rt].lazy*(node[rt].r-mid);
        node[rt].lazy = 0;
        
    }
    void build(int x,int l,int r){
        if((node[x].l = l) == (node[x].r = r)) return;
        int mid = node[x].l+node[x].r>>1;
        build(x<<1,l,mid),build(x<<1|1,mid+1,r);
    }
    //单点更新 
    void add_one(int rt,int pos,long long val){ 
        if(node[rt].l == node[rt].r){
            node[rt].val+=val;
            return;
        }
        int mid = node[rt].l+node[rt].r>>1;
        add_one(rt<<1|pos>mid,pos,val);
        pushup(rt);
    }
    //区域更新 
    //所谓lazy就是只有当需要pushdown时才pushdown,query同 
    void add(int rt,int l,int r,int val){ 
        pushdown(rt); // 这一行的作用见 https://jecvay.com/2014/11/segment-tree-lazy-design.html 
        if(node[rt].l>=l && node[rt].r<=r){  
            node[rt].val+=val*(node[rt].r-node[rt].l+1);
            node[rt].lazy += val;
            return ;
        }
        int mid = node[rt].l+node[rt].r>>1;
        if(l<=mid) add(rt<<1,l,r,val);
        if(r>mid) add(rt<<1|1,l,r,val);
        pushup(rt);
    }
    long long query(int rt,int l,int r){
        pushdown(rt); 
        if(node[rt].l>=l && node[rt].r<=r) return node[rt].val;
        int mid = node[rt].l + node[rt].r >> 1;
        long long ans = 0;
        if(l<=mid) ans+=query(rt<<1,l,r); // 易错 
        if(r>mid) ans+=query(rt<<1|1,l,r);
        return ans;
    }
    int main(){
        n = read(), m = read();
        build(1,0,n);
        for(int i = 0;i<n;i++) add_one(1,i,read());
        for(int i = 0;i<m;i++){
            op = read();_l = read()-1; _r = read()-1;
            if(op-1) printf("%lld
    ",query(1,_l,_r));
            else{
                k = read();
                add(1,_l,_r,k);
            }
        }
        return 0;
    }
  • 相关阅读:
    SPOJ GSS1 ~ 8解题报告 【完整版】
    题解 UVA1659 【帮助小罗拉 Help Little Laura】
    题解 UVA753 【UNIX插头 A Plug for UNIX】
    题解 P3740 【[HAOI2014]贴海报】
    对拍程序
    dut新生大礼包3
    1240C
    DISCO Presents Discovery Channel Code Contest 2020 Qual 题解
    1254C
    1285E
  • 原文地址:https://www.cnblogs.com/Invisible-full-moon/p/7468271.html
Copyright © 2020-2023  润新知