zoukankan      html  css  js  c++  java
  • HYSBZ 3224 Tyvj 1728 普通平衡树 splay模版

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3224

    splay详解: http://blog.csdn.net/clove_unique/article/details/50630280

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define lson i<<1
    #define rson i<<1|1
    using namespace std;
    const int N=1e5+5;
    int f[N],ch[N][2],sz[N],cnt[N],key[N];
    int tot,root;
    inline void Clear(int x)
    {
        ch[x][0]=ch[x][1]=f[x]=sz[x]=cnt[x]=key[x]=0;
    }
    inline int get(int x)
    {
        return ch[f[x]][1]==x;
    }
    void update(int x)
    {
        if (x)
        {
            sz[x]=cnt[x];
            if (ch[x][0]) sz[x]+=sz[ch[x][0]];
            if (ch[x][1]) sz[x]+=sz[ch[x][1]];
        }
    }
    void Rotate(int x)
    {
        int fa=f[x],ff=f[fa],kind=get(x);
        ch[fa][kind]=ch[x][kind^1];f[ch[x][kind^1]]=fa;
        ch[x][kind^1]=fa;f[fa]=x;
        f[x]=ff;
        if (ff)
            ch[ff][ch[ff][1]==fa]=x;
        update(fa);
        update(x);
    }
    void splay(int x)
    {
        for(int fa;(fa=f[x]);Rotate(x))
            if (f[fa])
                Rotate((get(x)==get(fa)?fa:x));
        root=x;
    }
    void Insert(int x)
    {
        if (root==0)
        {
            tot++;
            ch[tot][0]=ch[tot][1]=f[tot]=0;
            sz[tot]=cnt[tot]=1;
            key[tot]=x;
            root=tot;
            return;
        }
        int now=root,fa=0;
        while(1)
        {
            if (x==key[now])
            {
                cnt[now]++;
                update(now);
                update(fa);
                splay(now);
                return;
            }
            fa=now;
            now=ch[now][key[now]<x];
            if (now==0)
            {
                tot++;
                ch[tot][0]=ch[tot][1]=0;
                f[tot]=fa;
                sz[tot]=cnt[tot]=1;
                ch[fa][key[fa]<x]=tot;
                key[tot]=x;
                update(fa);
                splay(tot);
                return;
            }
        }
    }
    int Find(int x)
    {
        int now=root,ans=0;
        while(1)
        {
            if (x<key[now])
                now=ch[now][0];
            else
            {
                ans+=(ch[now][0])?sz[ch[now][0]]:0;
                if (x==key[now])
                {
                    splay(now);
                    return ans+1;
                }
                ans+=cnt[now];
                now=ch[now][1];
            }
        }
    }
    int Findx(int x)
    {
        int now=root;
        while(1)
        {
            if (ch[now][0]&&x<=sz[ch[now][0]])
                now=ch[now][0];
            else
            {
                int tem=ch[now][0]?sz[ch[now][0]]:0;
                tem+=cnt[now];
                if (x<=tem) return key[now];
                x-=tem;now=ch[now][1];
            }
        }
    }
    int pre()
    {
        int now=ch[root][0];
        while(ch[now][1]) now=ch[now][1];
        return now;
    }
    int nextt()
    {
        int now=ch[root][1];
        while(ch[now][0]) now=ch[now][0];
        return now;
    }
    void del(int x)
    {
        Find(x);
        if (cnt[root]>1)
        {
            cnt[root]--;
            return;
        }
        if (!ch[root][0]&&!ch[root][1])
        {
            Clear(root);
            root=0;
            return;
        }
        if (!ch[root][0])
        {
            int oldroot=root;
            root=ch[root][1];
            f[root]=0;
            Clear(oldroot);
            return;
        }
        else if (!ch[root][1])
        {
            int oldroot=root;
            root=ch[root][0];
            f[root]=0;
            Clear(oldroot);
            return;
        }
        int leftbig=pre(),oldroot=root;
        splay(leftbig);
        f[ch[oldroot][1]]=root;//因为提上来的是最靠近的数,所以不会产生左子树
        ch[root][1]=ch[oldroot][1];
        Clear(oldroot);
        update(root);
    }
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            tot=root=0;
            int opt,x;
            for(int i=1;i<=n;i++)
            {
                scanf("%d%d",&opt,&x);
                switch(opt)
                {
                    case 1:Insert(x);break;
                    case 2:del(x);break;
                    case 3:printf("%d
    ",Find(x));break;
                    case 4:printf("%d
    ",Findx(x));break;
                    case 5:Insert(x);printf("%d
    ",key[pre()]);del(x);break;
                    case 6:Insert(x);printf("%d
    ",key[nextt()]);del(x);break;
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    vue组件重新加载的方法
    事件触发方法获取当前值的写法 (含方法要传2个参数的写法)
    mac 解压 rar压缩文件
    表格
    小米8安装charles证书方法
    视频结构化技术栈全解析
    多目标跟踪全解析,全网最全
    SpringBoot
    技术方案设计的方法
    Java的强引用、软引用、弱引用、虚引用
  • 原文地址:https://www.cnblogs.com/bk-201/p/7383758.html
Copyright © 2011-2022 走看看