zoukankan      html  css  js  c++  java
  • 数组splay ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

    二次联通门 : luogu P3369 【模板】普通平衡树(Treap/SBT)

    #include <cstdio>
    
    #define Max 100005
    
    #define Inline __attri
    bute__( ( optimize( "-O2" ) ) )
    
    Inline void read (int &now)
    {
        now = 0;
        register char word = getchar ();
        bool temp = false;
        while (word < '0' || word > '9')
        {
            if (word == '-')
                temp = true;
            word = getchar ();
        }
        while (word <= '9' && word >= '0')
        {
            now = now * 10 + word - '0';
            word = getchar ();
        }
        if (temp)
            now = -now;
    }
    
    class Splay_Tree_Type
    {
        private:
            
            struct Tree_Date
            {
                int weigth;
                int size;
                int key;
                int child[2];
                int father;
            }
            tree[Max];
            
            Inline int Get_Son (int now)
            {
                return tree[tree[now].father].child[1] == now;
            }
            
            int Count;
            int Root;
            
        public :
            
            Inline void Update (int now)
            {
                tree[now].size = tree[now].weigth;
                if (tree[now].child[0])
                    tree[now].size += tree[tree[now].child[0]].size;
                if (tree[now].child[1])
                    tree[now].size += tree[tree[now].child[1]].size;
            }
            
            Inline void Rotate (int now)
            {
                int father = tree[now].father;
                int Grand = tree[father].father;
                int pos = Get_Son (now);
                tree[father].child[pos] = tree[now].child[pos ^ 1];
                tree[tree[father].child[pos]].father = father;
                tree[now].child[pos ^ 1] = father;
                tree[father].father = now;
                tree[now].father = Grand;
                if (Grand)
                    tree[Grand].child[tree[Grand].child[1] == father] = now;
                Update (father);
                Update (now);
            }
            
            Inline void Splay (int now)
            {
                for (int father; father = tree[now].father; Rotate (now))
                    if (tree[father].father)
                        Rotate (Get_Son (now) == Get_Son (father) ? father : now);
                Root = now;
            }
            
            Inline int Find_Prefix ()
            {
                int now = tree[Root].child[0];
                while (tree[now].child[1])
                    now = tree[now].child[1];
                return now;
            }
             
            Inline int Find_Suffix ()
            {
                int now = tree[Root].child[1];
                while (tree[now].child[0])
                    now = tree[now].child[0];
                return now;
            }
            
            Inline void Clear (int now)
            {
                tree[now].child[1] = 0;
                tree[now].child[1] = 1;
                tree[now].size = 0;
                tree[now].weigth = 0;
                tree[now].key = 0;
                tree[now].father = 0;
            }
            
            Inline int Find_x_rank (int x)
            {
                int now = Root;
                int Answer = 0;
                while (true)
                {
                    if (x < tree[now].key)
                    {
                        now = tree[now].child[0];
                        continue;
                    }
                    Answer += tree[now].child[0] ? tree[tree[now].child[0]].size : 0;
                    if (tree[now].key == x)
                    {
                        Splay (now);
                        return Answer + 1;
                    }
                    Answer += tree[now].weigth;
                    now = tree[now].child[1];
                }
            }
            
            Inline int Find_rank_x (int x)
            {
                int now = Root;
                while (true)
                {
                    if (tree[now].child[0] && x <= tree[tree[now].child[0]].size)
                    {
                        now = tree[now].child[0];
                        continue;
                    }
                    int temp = (tree[now].child[0] ? tree[tree[now].child[0]].size : 0) + tree[now].weigth;
                    if (x <= temp)
                        return tree[now].key;
                    x -= temp;
                    now = tree[now].child[1];
                }
            }
            
            Inline void Insert (int x)
            {
                if (!Root)
                {
                    Count++;
                    tree[Count].key = x;
                    tree[Count].size = 1;
                    tree[Count].weigth = 1;
                    Root = Count;
                    return;
                }
                int father = 0, now = Root;
                while (true)
                {
                    if (tree[now].key == x)
                    {
                        tree[now].size++;
                        tree[now].weigth++;
                        Splay (now);
                        return ;
                    }
                    father = now;
                    now = tree[now].child[x > tree[father].key];
                    if (!now)
                    {
                        Count++;
                        tree[father].child[x > tree[father].key] = Count;
                        tree[Count].father = father;
                        tree[Count].key = x;
                        tree[Count].size = 1;
                        tree[Count].weigth = 1;
                        Splay (Count);
                        return ;
                    }
                }
            }
            
            Inline void Delete (int x)
            {
                Find_x_rank (x);
                if (tree[Root].weigth > 1)
                {
                    tree[Root].weigth--;
                    tree[Root].size--;
                    return ;
                }
                if (!tree[Root].child[0] && !tree[Root].child[1])
                {
                    Clear (Root);
                    Root = 0;
                    return ;
                }
                if (!tree[Root].child[0])
                {
                    int temp = Root;
                    Root = tree[Root].child[1];
                    tree[Root].father = 0;
                    Clear (temp);
                    return ;
                }
                if (!tree[Root].child[1])
                {
                    int temp = Root;
                    Root = tree[Root].child[0];
                    tree[Root].father = 0;
                    Clear (temp);
                    return ;
                }
                int Prefix = Find_Prefix ();
                int temp = Root;
                Splay (Prefix);
                tree[Root].child[1] = tree[temp].child[1];
                tree[tree[temp].child[1]].father = Root;
                Clear (temp);
                Update (Root);
            }
            
            Inline int Get_tree_value (int now)
            {
                return tree[now].key;
            }
    };
    
    Splay_Tree_Type Splay_Tree;
    
    int main (int argc, char *argv[])
    {
        int N;
        
        read (N);
        int type, x;
        
        for (; N--; )
        {
            read (type);
            read (x);
            if (type == 1)
                Splay_Tree.Insert (x);
            else if (type == 2)
                Splay_Tree.Delete (x);
            else if (type == 3)
                printf ("%d
    ", Splay_Tree.Find_x_rank (x));
            else if (type == 4)
                printf ("%d
    ", Splay_Tree.Find_rank_x (x));
            else if (type == 5)
            {
                Splay_Tree.Insert (x);
                printf ("%d
    ", Splay_Tree.Get_tree_value (Splay_Tree.Find_Prefix ()));
                Splay_Tree.Delete (x); 
            }
            else
            {
                Splay_Tree.Insert (x);
                printf ("%d
    ", Splay_Tree.Get_tree_value (Splay_Tree.Find_Suffix ()));
                Splay_Tree.Delete (x);  
            }
        }
        
        return 0;
    }
  • 相关阅读:
    Centos6.6安装Nginx
    Centos6.6升级python版本
    基于Centos6.6的R720服务器四网口端口聚合的实践
    wcf 开发 1
    dev 转自
    SQL查询父节点下的所有子节点(包括子节点下的子节点,无限子节点)
    C# 自定义控件摘记
    C#中的自定义控件中的属性、事件及一些相关特性的总结(转)
    DevExpress控件-lookupedit的使用方法详解(图文)转http://blog.csdn.net/qq395537505/article/details/50920508
    【DevExpress】 SearchLookUpEdit
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7222954.html
Copyright © 2011-2022 走看看