• [模板] 线段树


    最规整的版本。
    玩火需谨慎(&)

    //Writer:GhostCai && His Yellow Duck
    
    #include<iostream>
    using namespace std;
    
    const long long MAXN=200005;
    
    long long n,m;
    long long a[MAXN];
    
    struct Node{
        long long sum;
        long long ls,rs,l,r;
        long long lazy;
    }node[MAXN];
    long long cnt,root;
    
    void pushup(long long now){
        Node &o=node[now];
        Node &nl=node[o.ls],&nr=node[o.rs];
        o.sum = nl.sum + nr.sum ;
        o.l = nl.l ;
        o.r = nr.r ;
    }
    
    void pushdown(long long now){
        Node &o=node[now];
        Node &nl=node[o.ls],&nr=node[o.rs];
        nl.lazy +=o.lazy ;
        nr.lazy +=o.lazy ;
        nl.sum +=o.lazy *(nl.r-nl.l+1);
        nr.sum +=o.lazy *(nr.r-nr.l+1);
        o.lazy = 0;
    }
    
    void build(long long L,long long R,long long now){
        Node &o=node[now]; 
        if(L==R){
            o.sum = a[L];
            o.ls = o.rs =-1;
            o.l = o.r = L;
            return ;
        }
        long long mid=(L+R)>>1;
        build(L,mid,o.ls=cnt++);
        build(mid+1,R,o.rs=cnt++);
        pushup(now);
    }
    
    long long query(long long L,long long R,long long now){
        Node &o=node[now];
        Node &nl=node[o.ls],&nr=node[o.rs];
        if(L<=o.l&&o.r<=R) return o.sum ;
        pushdown(now);
        long long mid=(o.l +o.r )>>1;
        long long sum=0;
        if(L<=mid) sum+=query(L,R,o.ls);
        if(mid<R)  sum+=query(L,R,o.rs);
        return sum;
    }
    
    void updata(long long L,long long R,long long w,long long now){
        Node &o=node[now];
        Node &nl=node[o.ls],&nr=node[o.rs];
        if(L<=o.l&&o.r<=R){
            o.sum +=w*(o.r-o.l+1);
            o.lazy +=w;
            return ;
        }
        pushdown(now);
        long long mid=(o.l+o.r)>>1;
        if(L<=mid) updata(L,R,w,o.ls);
        if(mid< R) updata(L,R,w,o.rs);
        pushup(now); 
    }
    
    int main(){
        cin>>n>>m;
        for(long long i=1;i<=n;i++) cin>>a[i];
        build(1,n,root=cnt++);
        long long q,x,y,z;
        for(long long i=1;i<=m;i++){
            cin>>q;
            if(q==1){
                cin>>x>>y>>z;
                updata(x,y,z,root);
            }else{
                cin>>x>>y;
                cout<<query(x,y,root)<<endl;
            }
        }
    }
    
    

    好写的版本

    //Stay foolish,stay hungry,stay young,stay simple
    #include<iostream>
    #define ls now<<1
    #define rs now<<1|1
    using namespace std;
    
    const int MAXN=200000;
    
    int val[MAXN],lazy[MAXN];
    int a[MAXN]; 
    void pushup(int now){
        val[now]=val[ls]+val[rs];
    }
    
    void pushdown(int now,int l,int r){
        int mid=(l+r)>>1;
        lazy[ls]+=lazy[now];
        lazy[rs]+=lazy[now];
        val[ls]+=lazy[now]*(mid-l+1);
        val[rs]+=lazy[now]*(r-mid); 
        lazy[now]=0;
    }
    
    void build(int L,int R,int now){
        if(L==R){
            val[now]=a[L];// 
            return ;
        }
        int mid=(L+R)>>1;
        build(L,mid,ls);
        build(mid+1,R,rs);
        pushup(now);
    }
    
    void updata(int L,int R,int l,int r,int now,int w){
        if(L<=l&&r<=R){
            lazy[now]+=w;
            val[now]+=w*(r-l+1);
            return ; 
        }
        pushdown(now,l,r);
        int mid=(l+r)>>1;
        if(L<=mid) updata(L,R,l,mid,ls,w);
        if(mid <R) updata(L,R,mid+1,r,rs,w);
        pushup(now);
    }
    
    int query(int L,int R,int l,int r,int now){
        if(L<=l&&r<=R){
            return val[now];
        }
        int mid=(l+r)>>1;
        int ret=0;
        pushdown(now,l,r);
        if(L<=mid) ret+=query(L,R,l,mid,ls);
        if(mid <R) ret+=query(L,R,mid+1,r,rs);
        return ret;
    }
    
    int n,m;
    
    int main(){
        cin>>n>>m;
        for(int i=1;i<=n;i++) cin>>a[i];
        build(1,n,1);
        for(int i=1;i<=m;i++){
            int q,x,y,z;
            cin>>q;
            if(q==1){
                cin>>x>>y>>z;
                updata(x,y,1,n,1,z);
            }else{
                cin>>x>>y;
                cout<<query(x,y,1,n,1)<<endl;
            }
        }
        return 0;
    }
    

    乘法标记+封装

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define int long long
    using namespace std;
    
    const int MAXN=300005;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    int p;
    
    struct Seg{
        #define ls now<<1
        #define rs now<<1|1
        #define mid ((l+r)>>1)
    
        int sum[MAXN],add[MAXN],mut[MAXN],a[MAXN];
    
        void pushup(int now){sum[now]=sum[ls]+sum[rs];}
    
        void pushdown(int now,int l,int r){
            mut[now]%=p;add[now]%=p;
            mut[ls]*=mut[now];mut[ls]%=p;
            mut[rs]*=mut[now];mut[rs]%=p;
            add[ls]=add[ls]*mut[now]+add[now];
            add[rs]=add[rs]*mut[now]+add[now];
            sum[ls]=sum[ls]*mut[now]+(mid-l+1)*add[now];
            sum[rs]=sum[rs]*mut[now]+(r-mid)*add[now];
            add[ls]%=p;add[rs]%=p;sum[ls]%=p;sum[rs]%=p;
            add[now]=0;mut[now]=1;
        }
    
        void build(int now,int l,int r){
            if(l==r){sum[now]=a[l];mut[now]=1;return;}
            build(ls,l,mid);
            build(rs,mid+1,r);
            mut[now]=1;//
            pushup(now);
        }
    
        void updata_mut(int L,int R,int w,int now,int l,int r){
            if(L<=l&&r<=R){sum[now]*=w;sum[now]%=p;mut[now]*=w;mut[now]%=p;add[now]*=w;add[now]%=p;return;}
            pushdown(now,l,r);
            if(L<=mid) updata_mut(L,R,w,ls,l,mid);
            if(mid <R) updata_mut(L,R,w,rs,mid+1,r);
            pushup(now);
        }
    
        void updata_add(int L,int R,int w,int now,int l,int r){
            if(L<=l&&r<=R){sum[now]+=w*(r-l+1);sum[now]%=p;add[now]+=w;add[now]%=p;return;}
            pushdown(now,l,r);
            if(L<=mid) updata_add(L,R,w,ls,l,mid);
            if(mid <R) updata_add(L,R,w,rs,mid+1,r);
            pushup(now);
        }
    
        int query(int L,int R,int now,int l,int r){
            if(L<=l&&r<=R){return sum[now];}
            pushdown(now,l,r);
            int ret=0;
            if(L<=mid) ret+=query(L,R,ls,l,mid),ret%=p;
            if(mid <R) ret+=query(L,R,rs,mid+1,r),ret%=p;
            return ret%p;
        }
    }t;
    
    int n,m;
    
    signed main(){
        n=rd();m=rd();p=rd();
        for(int i=1;i<=n;i++) t.a[i]=rd();
        t.build(1,1,n);
        for(int i=1;i<=m;i++){
            int x,y,w,q;
            q=rd();
            switch(q){
                case 1:{
                    x=rd();y=rd();w=rd();
                    t.updata_mut(x,y,w%p,1,1,n);
                    break;
                }
                case 2:{
                    x=rd();y=rd();w=rd();
                    t.updata_add(x,y,w%p,1,1,n);
                    break;
                }
                case 3:{
                    x=rd();y=rd();
                    printf("%d
    ",t.query(x,y,1,1,n));
                    break;
                }
            }
        }
        return 0;
    }

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9247488.html

  • 相关阅读:
    JavaFX学习曲线日记2:声明用户接口
    深入学习JavaFX脚本语言
    JavaFX学习曲线日记2:声明用户接口
    JavaFX学习曲线日记1:探索JavaFX脚本
    深入学习JavaFX脚本语言
    略谈数学中的映射在其它领域的踪迹
    Using Swing's Pluggable Look and Feel
    JavaFX学习曲线日记1:探索JavaFX脚本
    赖勇浩:应对多核编程革命
    Using Swing's Pluggable Look and Feel
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9247488.html
Copyright © 2020-2023  润新知