zoukankan      html  css  js  c++  java
  • 用各种奇怪的姿势写线段树练习3

    线段树练习3是一道codevs上的题目...区间加一个数、区间求和

    反正大部分一维数据结构都能过这道题...

    区修区查树状数组

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    using namespace std;
    typedef long long ll;
    int n,a,m,d,l,r,x;
    ll a1[200001],a2[200001];
    ll qzh(int r)
    {
        ll s1=0,s2=0;
        for(int i=r;i>=1;i-=i&-i) s1+=a1[i], s2+=a2[i];
        return (r+1)*s1-s2;
    }
    ll sum(int l,int r)
    {
        return qzh(r)-qzh(l-1);
    }
    void edt(ll a,ll s1)
    {
        ll s2=a*s1;
        for(;a<=n;a+=a&-a) a1[a]+=s1, a2[a]+=s2;
    }
    void edt(int l,int r,ll a) {edt(l,a); edt(r+1,-a);}
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a);
            edt(i,i,a);
        }
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&d);
            if(d==1)
            {
                scanf("%d%d%d",&l,&r,&x);
                edt(l,r,x);
            }
            else
            {
                scanf("%d%d",&l,&r);
                printf("%lld
    ",sum(l,r));
            }
        }
    }

    线段树 标记永久化

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <algorithm>
    #include <string.h>
    #include <math.h>
    #include <set>
    #include <map>
    using namespace std;
    int n;
    typedef long long ll;
    namespace seg
    {
    #define SZ 555555
    int M=262144,M2=M+M;
    ll sum[SZ],tag[SZ];
    void edit(int x,int ql,int qr,int v,int l,int r)
    {
        if(x>M2||ql>qr||l>r) return;
        if(ql==l&&qr==r) {tag[x]+=v; return;}
        sum[x]+=(qr-ql+1)*v;
        int mid=l+r>>1;
        edit(x+x,ql,min(qr,mid),v,l,mid);
        edit(x+x+1,max(mid+1,ql),qr,v,mid+1,r);
    }
    ll gsum(int x,int ql,int qr,int l,int r)
    {
        if(x>M2||ql>qr) return 0;
        if(ql==l&&qr==r) return sum[x]+tag[x]*(qr-ql+1);
        int mid=l+r>>1;
        return gsum(x+x,ql,min(qr,mid),l,mid)+gsum(x+x+1,max(mid+1,ql),qr,mid+1,r)+tag[x]*(qr-ql+1);
    }
    }
    int q,a,b,c;
    char buf[3];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            int a=i,b; scanf("%d",&b);
            seg::edit(1,a,a,b,1,n);
        }
        scanf("%d",&q);
        while(q--)
        {
            scanf("%s",buf);
            if(buf[0]=='2')
            {
                scanf("%d%d",&a,&b);
                printf("%lld
    ",seg::gsum(1,a,b,1,n));
            }
            else
            {
                scanf("%d%d%d",&a,&b,&c);
                seg::edit(1,a,b,c,1,n);
            }
        }
    }

    线段树 lazytag(不建议学习

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <algorithm>
    #include <string.h>
    #include <math.h>
    #include <set>
    #include <map>
    using namespace std;
    int n;
    typedef long long ll;
    namespace seg
    {
    #define SZ 555555
    int M=262144,M2=M+M,ls[SZ],rs[SZ];
    ll sum[SZ],tag[SZ];
    void build()
    {
        for(int i=M+1;i<=M+M;i++) ls[i]=rs[i]=i-M;
        for(int i=M-1;i;i--) ls[i]=ls[i+i], rs[i]=rs[i+i+1], sum[i]=sum[i+i]+sum[i+i+1];
    }
    void pd(int x)
    {
        if(tag[x])
        {
            sum[x]+=tag[x]*(rs[x]-ls[x]+1);
            if(x+x<=M2) tag[x+x]+=tag[x], tag[x+x+1]+=tag[x];
            tag[x]=0;
        }
    }
    void upd(int x)
    {
        pd(x+x); pd(x+x+1);
        sum[x]=sum[x+x]+sum[x+x+1];
    }
    void edit(int x,int ql,int qr,int v)
    {
        if(x>M2||ql>qr) return;
        pd(x);
        if(ql==ls[x]&&qr==rs[x]) {tag[x]+=v; return;}
        int mid=ls[x]+rs[x]>>1;
        edit(x+x,ql,min(qr,mid),v);
        edit(x+x+1,max(mid+1,ql),qr,v);
        upd(x);
    }
    ll gsum(int x,int ql,int qr)
    {
        if(x>M2||ql>qr) return 0;
        pd(x);
        if(ql==ls[x]&&qr==rs[x]) return sum[x];
        int mid=ls[x]+rs[x]>>1;
        ll ans=gsum(x+x,ql,min(qr,mid))+gsum(x+x+1,max(mid+1,ql),qr);
        upd(x); return ans;
    }
    }
    int q,a,b,c;
    char buf[3];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%lld",&seg::sum[i+seg::M]);
        scanf("%d",&q); seg::build();
        while(q--)
        {
            scanf("%s",buf);
            if(buf[0]=='2')
            {
                scanf("%d%d",&a,&b);
                printf("%lld
    ",seg::gsum(1,a,b));
            }
            else
            {
                scanf("%d%d%d",&a,&b,&c);
                seg::edit(1,a,b,c);
            }
        }
    }

    splay

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <algorithm>
    #include <string.h>
    #include <vector>
    #include <limits>
    #include <set>
    #include <map>
    using namespace std;
    #define SZ 233333
    typedef long long ll;
    #define R register
    int ch[SZ][2],fa[SZ],org[SZ],root,an=0,sz[SZ];
    ll sum[SZ],tag[SZ],val[SZ];
    void pd(R int x)
    {
        if(!x||!tag[x]) return;
        val[x]+=tag[x];
        R int &lc=ch[x][0],&rc=ch[x][1];
        if(lc) {tag[lc]+=tag[x]; sum[lc]+=tag[x]*sz[lc];}
        if(rc) {tag[rc]+=tag[x]; sum[rc]+=tag[x]*sz[rc];}
        tag[x]=0;
    }
    void upd(R int x)
    {
        R int &lc=ch[x][0],&rc=ch[x][1];
        pd(lc); pd(rc);
        sz[x]=sz[lc]+sz[rc]+1;
        sum[x]=val[x]+tag[x]+sum[lc]+sum[rc];
    }
    void rot(R int x)
    {
        if(!fa[x]) return;
        pd(fa[x]); pd(x);
        R int y=fa[x],c=ch[y][0]==x,&f=fa[y],&s=ch[x][c];
        fa[x]=f; if(f) ch[f][ch[f][1]==y]=x; f=x;
        ch[y][!c]=s; if(s) fa[s]=y; s=y;
        upd(y); if(y==root) root=x;
    }
    void splay(R int x,R int f)
    {
        pd(x);
        R int& y=fa[x];
        while(y!=f)
        {
            if(fa[y]!=f)
            {
                if(ch[fa[y]][0]==y^ch[y][0]==x) rot(x);
                else rot(y);
            }
            rot(x);
        }
        upd(x);
        if(!f) root=x;
    }
    void splayp(R int k,R int f)
    {
        R int x=root; pd(x);
        while(sz[ch[x][0]]!=k-1)
        {
            if(k<=sz[ch[x][0]]) x=ch[x][0];
            else k-=sz[ch[x][0]]+1, x=ch[x][1];
            pd(x);
        }
        splay(x,f);
    }
    int n,q,a,b,c,is[233333];
    char buf[3];
    void addnode(R int& x,R int f,R int v) {x=++an; fa[x]=f; val[x]=sum[x]=v; sz[x]=1;}
    void build(R int& x,R int l,R int r,R int f)
    {
        if(l>r) {x=0; return;}
        R int m=(l+r)>>1;
        addnode(x,f,is[m]);
        build(ch[x][0],l,m-1,x);
        build(ch[x][1],m+1,r,x);
        upd(x);
    }
    #define rrl ch[ch[root][1]][0]
    void build()
    {
        addnode(root,0,0);
        addnode(ch[root][1],root,0);
        upd(root);
        build(rrl,1,n,ch[root][1]);
        upd(ch[root][1]); upd(root);
    }
    void getlr(R int l,R int r) {splayp(l,0); splayp(r+2,root);}
    int main()
    {
        scanf("%d",&n);
        for(R int i=1;i<=n;i++) scanf("%d",is+i);
        build(); scanf("%d",&q);
        while(q--)
        {
            scanf("%s",buf);
            if(buf[0]=='2')
            {
                scanf("%d%d",&a,&b); getlr(a,b);
                printf("%lld
    ",sum[rrl]);
            }
            else
            {
                scanf("%d%d%d",&a,&b,&c); getlr(a,b);
                tag[rrl]+=c; sum[rrl]+=(ll)sz[rrl]*c;
            }
        }
    }

    treap

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <algorithm>
    #include <string.h>
    #include <math.h>
    #include <set>
    #include <map>
    using namespace std;
    #define ll long long
    #define SZ 233333
    int ch[SZ][2],sz[SZ],rnd[SZ],an=0,root;
    ll tag[SZ],val[SZ],sum[SZ];
    int Rand() {return rand()<<16+rand();}
    void addnode(int& ad,int x)
    {
        ad=++an; sz[ad]=1; rnd[ad]=Rand();
        sum[ad]=val[ad]=x;
    }
    void pd(int x)
    {
        if(!x||!tag[x]) return;
        val[x]+=tag[x];
        if(ch[x][0]) tag[ch[x][0]]+=tag[x], sum[ch[x][0]]+=tag[x]*sz[ch[x][0]];
        if(ch[x][1]) tag[ch[x][1]]+=tag[x], sum[ch[x][1]]+=tag[x]*sz[ch[x][1]];
        tag[x]=0;
    }
    void upd(int x)
    {
        if(!x) return;
        sz[x]=1+sz[ch[x][0]]+sz[ch[x][1]];
        sum[x]=val[x]+sum[ch[x][0]]+sum[ch[x][1]];
    }
    void split(int x,int& a,int& b,int s)
    {
        if(sz[x]<=s) a=x, b=0;
        else if(s==0) a=0, b=x;
        else
        {
            pd(x);
            if(sz[ch[x][0]]>=s)
            {
                b=x;
                split(ch[x][0],a,ch[x][0],s);
                upd(x);
            }
            else
            {
                a=x;
                split(ch[x][1],ch[x][1],b,s-sz[ch[x][0]]-1);
                upd(x);
            }
        }
    }
    void merge(int& ad,int a,int b)
    {
        if(a==0) ad=b;
        else if(b==0) ad=a;
        else
        {
            if(rnd[a]>rnd[b])
            {
                pd(ad=a); merge(ch[a][1],ch[a][1],b);
            }
            else
            {
                pd(ad=b); merge(ch[b][0],a,ch[b][0]);
            }
            upd(ad);
        }
    }
    void edit(int l,int r,ll v)
    {
        int a,b,c;
        split(root,a,b,l-1);
        split(b,b,c,r-l+1);
        tag[b]+=v;
        sum[b]+=v*sz[b];
        merge(a,a,b);
        merge(root,a,c);
    }
    ll query(int l,int r)
    {
        int a,b,c;
        split(root,a,b,l-1);
        split(b,b,c,r-l+1);
        ll ans=sum[b];
        merge(a,a,b);
        merge(root,a,c);
        return ans;
    }
    int n,ns[SZ];
    int ins(int l,int r)
    {
        if(l>r) return 0;
        if(l==r)
        {
            int ad;
            addnode(ad,ns[l]);
            return ad;
        }
        int mid=(l+r)>>1,lc=ins(l,mid),rc=ins(mid+1,r);
        merge(lc,lc,rc); return lc;
    }
    void init()
    {
        addnode(root,0);
        merge(root,ins(1,n),root);
    }
    int q,a,b,c;
    char buf[3];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&ns[i]);
        init(); scanf("%d",&q);
        while(q--)
        {
            scanf("%s",buf);
            if(buf[0]=='2')
            {
                scanf("%d%d",&a,&b);
                printf("%lld
    ",query(a,b));
            }
            else
            {
                scanf("%d%d%d",&a,&b,&c);
                edit(a,b,c);
            }
        }
    }

    下篇文章就写一点数据结构题好了...这篇就当是整理模板好了。

  • 相关阅读:
    智慧养老民政监管平台建设方案
    CF600E Lomsat gelral dsu on tree
    dsu on tree详解
    【Spring 从0开始】Spring5 新功能,整合日志框架 Log4j2
    【Spring 从0开始】JdbcTemplate 数据库事务管理
    【Spring 从0开始】JdbcTemplate 数据库事务参数
    【Spring 从0开始】JdbcTemplate 数据库事务管理
    【Spring 从0开始】JdbcTemplate 操作数据库
    【Spring 从0开始】AOP 操作
    【Spring 从0开始】AOP 操作中的相关术语、环境准备
  • 原文地址:https://www.cnblogs.com/zzqsblog/p/5692627.html
Copyright © 2011-2022 走看看