• 平衡树splay


    splay平衡树实现 留坑

    spaly权值平衡树:

    普通平衡树

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cmath>
    #include<map>
    #include<bitset>
    #define inf 2000000000
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define dwn(i,a,b) for(int i=(a);i>=(b);--i)
    using namespace std;
    typedef long long ll;
    const int N=100010;
    int n;
    int val[N+10],fa[N+10],ch[N+10][2],rec[N+10],sz[N+10];
    int &root=ch[0][1],tot=0;
    inline int newnode(int v,int f)
    {
        fa[++tot]=f;
        rec[tot]=sz[tot]=1;
        val[tot]=v;
        return tot;
    }
    inline void update(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+rec[x];}
    inline int ident(int x){return ch[fa[x]][0]==x?0:1;}
    inline void connect(int x,int f,int how){ch[f][how]=x,fa[x]=f;}
    void rotate(int x)
    {
        int Y=fa[x],R=fa[Y];
        int Yson=ident(x),Rson=ident(Y);
        connect(ch[x][Yson^1],Y,Yson);
        connect(Y,x,Yson^1);
        connect(x,R,Rson);
        update(Y);update(x);
    }
    void splay(int x,int to)
    {
        to=fa[to];
        while(fa[x]!=to)
        {
            int y=fa[x];
            if(fa[y]==to) rotate(x);
            else if(ident(x)==ident(y)) rotate(y),rotate(x);
            else rotate(x),rotate(x);
        }
    }
    void insert(int x)
    {
        if(root==0)
        {
            root=newnode(x,0);
            return;
        }
        int y=root;
        while(1)
        {
            sz[y]++;
            if(val[y]==x){rec[y]++;splay(y,root);return;}
            int nxt=x<val[y]?0:1;
            if(!ch[y][nxt])
            {
                ch[y][nxt]=newnode(x,y);
                splay(ch[y][nxt],root);
                return;
            }
            y=ch[y][nxt];
        }
    }
    int find(int x)
    {
        int y=root;
        while(1)
        {
            if(!y) return 0;
            if(val[y]==x){splay(y,root);return y;}
            int nxt=x<val[y]?0:1;
            y=ch[y][nxt];
        }
    }
    void del(int x)
    {
        int y=find(x);
        if(!y) return;
        if(rec[y]>=2){rec[y]--,sz[y]--;return;}
        if(!ch[y][0]&&!ch[y][1]){root=0;return;}
        if(!ch[y][0]){root=ch[y][1];fa[root]=0;return;}
        if(!ch[y][1]){root=ch[y][0];fa[root]=0;return;}
        int left=ch[y][0];
        while(ch[left][1]) left=ch[left][1];
        splay(left,ch[y][0]);
        connect(ch[y][1],left,1);
        connect(left,0,1);
        update(left);
    }
    int lower(int x)
    {
        int y=root,ans=-inf;
        while(y)
        {
            if(val[y]<x) ans=max(ans,val[y]);
            int nxt=x<=val[y]?0:1;
            y=ch[y][nxt];
        }
        return ans;
    }
    int upper(int x)
    {
        int y=root,ans=inf;
        while(y)
        {
            if(val[y]>x) ans=min(ans,val[y]);
            int nxt=x<val[y]?0:1;
            y=ch[y][nxt];
        }
        return ans;
    }
    int rk(int x)
    {
        int y=root,ans=0;
        while(1)
        {
            if(!y) return 0;
            if(val[y]==x){ans+=sz[ch[y][0]]+1;splay(y,root);return ans;}
            int nxt=x<val[y]?0:1;
            if(nxt==1) ans+=sz[ch[y][0]]+rec[y];
            y=ch[y][nxt];
        }
    }
    int kth(int x)
    {
        int y=root;
        while(1)
        {
            int used=sz[ch[y][0]]+rec[y];
            if(sz[ch[y][0]]<x&&x<=used){splay(y,root);return val[y];}
            if(x<used) y=ch[y][0];
            else y=ch[y][1],x-=used;
        }
    }
    int main()
    {
        scanf("%d",&n);
        while(n--)
        {
            int opt,x;
            scanf("%d%d",&opt,&x);
            if(opt==1) insert(x);
            if(opt==2) del(x);
            if(opt==3) printf("%d
    ",rk(x));
            if(opt==4) printf("%d
    ",kth(x));
            if(opt==5) printf("%d
    ",lower(x));
            if(opt==6) printf("%d
    ",upper(x));
        }
        return 0;
    }
    

    splay区间平衡树:

    文艺平衡树

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cmath>
    #include<map>
    #include<bitset>
    #define inf 2000000000
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define dwn(i,a,b) for(int i=(a);i>=(b);--i)
    using namespace std;
    typedef long long ll;
    const int N=100000;
    int n,m;
    int rev[N+10],sz[N+10],fa[N+10],ch[N+10][2];
    int root;
    inline void pushup(int x)
    {
        int l=ch[x][0],r=ch[x][1];
        sz[x]=sz[l]+sz[r]+1;
    }
    inline void pushdown(int x)
    {
        if(rev[x])
        {
            rev[x]=0;
            rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;
            swap(ch[ch[x][0]][0],ch[ch[x][0]][1]);
            swap(ch[ch[x][1]][0],ch[ch[x][1]][1]);
        }
    }
    inline int ident(int x){return x==ch[fa[x]][0]?0:1;}
    inline void connect(int x,int f,int how){ch[f][how]=x;fa[x]=f;}
    inline void rotate(int x)
    {
        int Y=fa[x],R=fa[Y],Yson=ident(x),Rson=ident(Y);
        connect(ch[x][Yson^1],Y,Yson);
        connect(Y,x,Yson^1);
        connect(x,R,Rson);
        pushup(Y),pushup(x);
        if(Y==root) root=x;
    }
    inline void splay(int x,int to)
    {
        to=fa[to];
        while(fa[x]!=to)
        {
            int y=fa[x];
            if(fa[y]==to) rotate(x);
            else if(ident(x)==ident(y)) rotate(y),rotate(x);
            else rotate(x),rotate(x);
        }
    }
    int find(int x,int rk)
    {
        pushdown(x);
        int l=ch[x][0],r=ch[x][1];
        if(rk==sz[l]+1) return x;
        else if(rk<=sz[l]) return find(l,rk);
        else return find(r,rk-sz[l]-1);
    }
    inline int split(int k1,int k2)
    {
        int x=find(root,k1),y=find(root,k2+2);
        splay(x,root),splay(y,ch[x][1]);
        return ch[y][0];
    }
    void build(int l,int r,int f)
    {
        int mid=(l+r)>>1;
        if(l<mid) build(l,mid-1,mid);
        if(r>mid) build(mid+1,r,mid);
        fa[mid]=f;
        ch[f][mid>=f]=mid;
        pushup(mid);
    }
    void print(int x)
    {
        if(!x) return;
        pushdown(x);
        print(ch[x][0]);
        if(x!=1&&x!=n+2) printf("%d ",x-1);
        print(ch[x][1]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        build(1,n+2,0);
        root=(n+3)>>1;
        rep(i,1,m)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            int x=split(l,r);
            rev[x]^=1;swap(ch[x][0],ch[x][1]);
        }
        print(root);
        putchar('
    ');
        return 0;
    }
    

    [NOI2005]维护数列

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cmath>
    #include<map>
    #include<bitset>
    #include<queue>
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define dwn(i,a,b) for(int i=(a);i>=(b);--i)
    using namespace std;
    typedef long long ll;
    const int inf=0x3f3f3f3f,N=500000;
    int n,m,cnt,root;
    int a[N+10],id[N+10],fa[N+10],ch[N+10][2];
    int sz[N+10],sum[N+10],v[N+10],mx[N+10],lx[N+10],rx[N+10];
    bool tag[N+10],rev[N+10];
    queue<int> que;
    inline int read()
    {
        int 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<<3)+(x<<1)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    inline void pushup(int x)
    {
        int l=ch[x][0],r=ch[x][1];
        sz[x]=sz[l]+sz[r]+1;
        sum[x]=sum[l]+sum[r]+v[x];
        mx[x]=max(rx[l]+lx[r]+v[x],max(mx[l],mx[r]));
        lx[x]=max(lx[l],sum[l]+lx[r]+v[x]);
        rx[x]=max(rx[r],sum[r]+rx[l]+v[x]);
    }
    inline void pushdown(int x)
    {
        int l=ch[x][0],r=ch[x][1];
        if(tag[x])
        {
            tag[x]=0,rev[x]=0;
            if(l) tag[l]=1,v[l]=v[x],sum[l]=sz[l]*v[x];
            if(r) tag[r]=1,v[r]=v[x],sum[r]=sz[r]*v[x];
            if(v[x]>=0)
            {
                if(l) mx[l]=lx[l]=rx[l]=sz[l]*v[x];
                if(r) mx[r]=lx[r]=rx[r]=sz[r]*v[x];
            }
            else
            {
                if(l) lx[l]=rx[l]=0,mx[l]=v[x];
                if(r) lx[r]=rx[r]=0,mx[r]=v[x];
            }
        }
        if(rev[x])
        {
            rev[x]=0,rev[l]^=1,rev[r]^=1;
            swap(ch[l][0],ch[l][1]);
            swap(ch[r][0],ch[r][1]);
            swap(lx[l],rx[l]);
            swap(lx[r],rx[r]);
        }
    }
    inline int ident(int x){return x==ch[fa[x]][0]?0:1;}
    inline int connect(int x,int f,int how){ch[f][how]=x;fa[x]=f;}
    inline void rotate(int x)
    {
        int Y=fa[x],R=fa[Y],Yson=ident(x),Rson=ident(Y);
        connect(ch[x][Yson^1],Y,Yson);
        connect(Y,x,Yson^1);
        connect(x,R,Rson);
        pushup(Y);pushup(x);
        if(Y==root) root=x;
    }
    inline void splay(int x,int to)
    {
        to=fa[to];
        while(fa[x]!=to)
        {
            int y=fa[x];
            if(fa[y]==to) rotate(x);
            else if(ident(x)==ident(y)) rotate(y),rotate(x);
            else rotate(x),rotate(x);
        }
    }
    int find(int x,int rk)
    {
        pushdown(x);
        int l=ch[x][0],r=ch[x][1];
        if(rk==sz[l]+1) return x;
        else if(rk<=sz[l]) return find(l,rk);
        else find(r,rk-sz[l]-1);
    }
    void recycle(int x)
    {
        int l=ch[x][0],r=ch[x][1];
        if(l) recycle(l);
        if(r) recycle(r);
        fa[x]=ch[x][0]=ch[x][1]=v[x]=sum[x]=mx[x]=lx[x]=rx[x]=sz[x]=tag[x]=rev[x]=0;
        que.push(x);
    }
    inline int split(int k,int tot)
    {
        int x=find(root,k),y=find(root,k+tot+1);
        splay(x,root),splay(y,ch[x][1]);
        return ch[y][0];
    }
    inline int ask_sum(int k,int tot)
    {
        int x=split(k,tot);
        return sum[x];
    }
    inline void ask_alt(int k,int tot,int d)
    {
        int x=split(k,tot),y=fa[x];
        tag[x]=1,v[x]=d,sum[x]=sz[x]*d;
        if(d>=0) mx[x]=lx[x]=rx[x]=sum[x];
        else lx[x]=rx[x]=0,mx[x]=d;
        pushup(y),pushup(fa[y]);
    }
    inline void ask_rev(int k,int tot)
    {
        int x=split(k,tot),y=fa[x];
        if(!tag[x])
        {
            rev[x]^=1;
            swap(lx[x],rx[x]);
            swap(ch[x][0],ch[x][1]);
            pushup(y),pushup(fa[y]);
        }
    }
    inline void del(int k,int tot)
    {
        int x=split(k,tot),y=fa[x];
        recycle(x);ch[y][0]=0;
        pushup(y),pushup(fa[y]);
    }
    inline void build(int l,int r,int f)
    {
        int mid=(l+r)>>1,now=id[mid],pre=id[f];
        if(l==r)
        {
            mx[now]=sum[now]=a[mid];
            lx[now]=rx[now]=max(0,a[mid]);
            sz[now]=1;
        }
        if(l<mid) build(l,mid-1,mid);
        if(r>mid) build(mid+1,r,mid);
        v[now]=a[mid];fa[now]=pre;
        ch[pre][mid>=f]=now;
        pushup(now);
    }
    void insert(int k,int tot)
    {
        rep(i,1,tot) a[i]=read();
        rep(i,1,tot)
            if(!que.empty())id[i]=que.front(),que.pop();
            else id[i]=++cnt;
        build(1,tot,0);
        int rt=id[(1+tot)>>1];
        int x=find(root,k+1),y=find(root,k+2);
        splay(x,root),splay(y,ch[x][1]);
        fa[rt]=y,ch[y][0]=rt;
        pushup(y),pushup(x);
    }
    int main()
    {
        n=read(),m=read();
        mx[0]=a[1]=a[n+2]=-inf;
        rep(i,2,n+1) a[i]=read();
        rep(i,1,n+2) id[i]=i;
        build(1,n+2,0);
        root=(n+3)>>1;cnt=n+2;
        while(m--)
        {
            int k,tot,d;
            string s;
            cin>>s;
            if(s=="INSERT")
            {
                k=read(),tot=read();
                insert(k,tot);
            }
            if(s=="DELETE")
            {
                k=read(),tot=read();
                del(k,tot);
            }
            if(s=="MAKE-SAME")
            {
                k=read(),tot=read(),d=read();
                ask_alt(k,tot,d);
            }
            if(s=="REVERSE")
            {
                k=read(),tot=read();
                ask_rev(k,tot);
            }
            if(s=="GET-SUM")
            {
                k=read(),tot=read();
                printf("%d
    ",ask_sum(k,tot));
            }
            if(s=="MAX-SUM")
            {
                printf("%d
    ",mx[root]);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    用dos批处理程序检测是否安装.netframework,并自动安装后运行指定程序(.net自启动光盘的制做)
    生成pdf文件的好东西,itextsharp
    阳春三月来了
    新年快乐!
    无法启动 MS DTC 事务管理器。LogInit 返回错误 0x2. 怎么办?
    如何获取文件在系统中的图标?
    自定义工作流程的实现方案(初稿)
    [正能量系列]女性程序员篇
    [正能量系列]失业的程序员(一)
    我们在囧途之裁员篇
  • 原文地址:https://www.cnblogs.com/MYsBlogs/p/11360894.html
Copyright © 2020-2023  润新知