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);
            }
        }
    }

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

  • 相关阅读:
    SQL SERVER 2000 配置文件 SETUP.INI
    (转)Sybase ASE基础知识:利用Sybase Central简单操作Sybase ASE数据库
    新软发布:Autorun病毒免疫工具
    vc 编程最需要注意的地方
    (转)不得不了解VB中的CallByName
    作业总结
    (转)傻瓜式简单制作Windows7旗舰版免激活光盘镜像教程 (安装后自动激活)
    发布C#模块:平面凸包的计算
    凸包计算模块ConvexHull的使用方法
    模块发布——树类模块
  • 原文地址:https://www.cnblogs.com/zzqsblog/p/5692627.html
Copyright © 2011-2022 走看看