zoukankan      html  css  js  c++  java
  • 线段树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;
    }
  • 相关阅读:
    [CQOI2017] 小Q的棋盘
    CF75D Big Maximum Sum
    Dockerfile
    docker镜像与容器的导出导入
    ubuntu安装glusterFS
    常用工具网站网址
    国内数据分析平台
    清理系统垃圾
    sql注入笔记
    shopify Liquid语言学习知识点总结
  • 原文地址:https://www.cnblogs.com/Invisible-full-moon/p/7468271.html
Copyright © 2011-2022 走看看