线段树板子

耗费了两天$AC$了线段树的两道模板。就把我自己的代码贴出来以后$DEBUG$的时候做个参考吧。

线段树壹

#include <cstdio>

typedef long long ll;
const int N = 100000+10;

int n,m;
ll a[N];

struct Segment_Tree {

    #define lson (o<<1)
    #define rson (o<<1|1)

    ll sumv[N<<2],addv[N<<2];

    void pushup(int o) {
        sumv[o]=sumv[lson]+sumv[rson];
    }

    void pushdown(int o,int l,int r) {
        if(addv[o]) {
            int mid=(l+r)>>1;
            sumv[lson]+=addv[o]*(mid-l+1);
            sumv[rson]+=addv[o]*(r-mid);
            addv[lson]+=addv[o];
            addv[rson]+=addv[o];
            addv[o]=0;
        }
    }

    void bulid(int o,int l,int r) {
        if(l == r) {
            sumv[o]=a[l];
            return ;
        }
        addv[o]=0;
        int mid=(l+r)>>1;
        bulid(lson,l,mid);bulid(rson,mid+1,r);
        pushup(o);
    }

    void change(int o,int l,int r,int q,ll v) {
        if(l == r) {
            sumv[o]+=v;
        }
        int mid=(l+r)>>1;
        if(q <= mid) {
            change(lson,l,mid,q,v);
        } else {
            change(rson,mid+1,r,q,v);
        }
        pushup(o);
    }

    void optadd(int o,int l,int r,int ql,int qr,ll v) {
        if(ql<=l && r<=qr) {
            addv[o]+=v;sumv[o]+=(r-l+1)*v;
            return ;
        }
        int mid=(l+r)>>1;
        pushdown(o,l,r);
        if(ql <= mid) {
            optadd(lson,l,mid,ql,qr,v);
        }
        if(qr > mid) {
            optadd(rson,mid+1,r,ql,qr,v);
        }
        pushup(o);
    }

    ll querysum(int o,int l,int r,int ql,int qr) {
        if(ql<=l && r<=qr) {
            return sumv[o];
        }
        int mid=(l+r)>>1;
        ll ans=0;
        pushdown(o,l,r);
        if(ql <= mid) {
            ans+=querysum(lson,l,mid,ql,qr);
        }
        if(qr > mid) {
            ans+=querysum(rson,mid+1,r,ql,qr);
        }
        return ans;
    }
};

int main(void) {
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++) {
        scanf("%lld",&a[i]);
    }
    Segment_Tree T;
    T.bulid(1,1,n);
    for(int i=1; i<=m; i++) {
        int k;
        scanf("%d",&k);
        if(k == 1) {
            ll x,y,v;
            scanf("%lld%lld%lld",&x,&y,&v);
            T.optadd(1,1,n,x,y,v);
        } else {
            ll x,y;
            scanf("%lld%lld",&x,&y);
            printf("%lld\n",T.querysum(1,1,n,x,y));
        }
    }
    return 0;
}

线段树贰

#include <cstdio>

int P;
const int N = 100000+10;
int a[N];
struct Segment_Tree {
    #define lson (o<<1)
    #define rson (o<<1|1) 
    #define ll long long 
    ll sumv[N<<2],addv[N<<2],mulv[N<<2];

    ll mul(ll a,ll b) {
        return (a*b)%P;
    }

    ll sum(ll a,ll b) {
        return (a+b)%P;
    }

    void pushup(int o) {
        sumv[o]=sum(sumv[lson],sumv[rson]);
    }

    void pushdown(int o,int l,int r) {
        if(!addv[o] && mulv[o] == 1) {
            return ;
        }
        int mid=(l+r)>>1; 
        sumv[lson]=mul(sumv[lson],mulv[o]);
        sumv[rson]=mul(sumv[rson],mulv[o]);
        mulv[lson]=mul(mulv[lson],mulv[o]);
        mulv[rson]=mul(mulv[rson],mulv[o]);
        sumv[lson]=sum(sumv[lson],addv[o]*(mid-l+1));
        sumv[rson]=sum(sumv[rson],addv[o]*(r-mid));
        addv[lson]=sum(mul(addv[lson],mulv[o]),addv[o]);
        addv[rson]=sum(mul(addv[rson],mulv[o]),addv[o]);
        addv[o]=0;mulv[o]=1;
    }

    void bulid(int o,int l,int r) {
        mulv[o]=1;
        addv[o]=0;
        if(l == r) {
            sumv[o]=a[l];
            return ;
        }
        int mid=(l+r)>>1;
        bulid(lson,l,mid);bulid(rson,mid+1,r);
        pushup(o);
    } 

    void optadd1(int o,int l,int r,int ql,int qr,int v) {
        if(ql<=l && r<=qr) {
            sumv[o]=mul(sumv[o],v);
            mulv[o]=mul(mulv[o],v);
            addv[o]=mul(addv[o],v);
            return ;
        } 
        int mid=(l+r)>>1;
        pushdown(o,l,r);
        if(ql <= mid) {
            optadd1(lson,l,mid,ql,qr,v);
        }
        if(qr >  mid) {
            optadd1(rson,mid+1,r,ql,qr,v);
        }
        pushup(o);
    }

    void optadd2(int o,int l,int r,int ql,int qr,int v) {
        if(ql<=l && r<=qr) {
            sumv[o]=sum(sumv[o],mul(v,(r-l+1)));addv[o]=sum(addv[o],v);
            return ;
        } 
        int mid=(l+r)>>1;
        pushdown(o,l,r);
        if(ql <= mid) {
            optadd2(lson,l,mid,ql,qr,v);
        }
        if(qr >  mid) {
            optadd2(rson,mid+1,r,ql,qr,v);
        }
        pushup(o);
    }

    ll querysum(int o,int l,int r,int ql,int qr) {
        if(ql<=l && r<=qr) {
            return sumv[o];
        } 
        int mid=(l+r)>>1;
        ll sum=0;
        pushdown(o,l,r);
        if(ql <= mid) {
            sum+=querysum(lson,l,mid,ql,qr);
        }
        if(qr >  mid) {
            sum+=querysum(rson,mid+1,r,ql,qr);
        }
        return sum;
    }
}T;

int main(void) {
    int n,m;
    scanf("%d%d%d",&n,&m,&P);
    for(int i=1; i<=n; i++) {
        scanf("%lld",&a[i]);
    }
    T.bulid(1,1,n);
    for(int i=1; i<=m; i++) {
        int p;
        scanf("%d",&p);
        if(p == 3) {
            int x,y;
            scanf("%d%d",&x,&y);
            printf("%lld\n",T.querysum(1,1,n,x,y)%P);
        } else {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            if(p == 1) {
                T.optadd1(1,1,n,x,y,z);
            } else {
                T.optadd2(1,1,n,x,y,z); 
            } 
        }
    }
    return 0;
}  
posted @ 2019-02-03 08:57  加固文明幻景  阅读(4)  评论(0编辑  收藏  举报  来源