zoukankan      html  css  js  c++  java
  • BZOJ 3224: Tyvj 1728 普通平衡树

    二次联通门 : BZOJ 3224: Tyvj 1728 普通平衡树

    /*
        BZOJ 3224: Tyvj 1728 普通平衡树
    
        splay 模板
        
        支持插入x数
        删除x数(若有多个相同的数,因只删除一个)
        查询x数的排名(若有多个相同的数,因输出最小的排名)
        查询排名为x的数
        求x的前驱(前驱定义为小于x,且最大的数)
        求x的后继(后继定义为大于x,且最小的数) 
        
    */
    #include <cstdio>
    
    #define Max 200005
    
    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);
            }
            
            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;
            }
            
            int Find_Prefix ()
            {
                int now = tree[Root].child[0];
                while (tree[now].child[1])
                    now = tree[now].child[1];
                return now;
            }
             
            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;
            }
            
            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];
                }
            }
            
            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];
                }
            }
            
            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 ;
                    }
                }
            }
            
            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)  // 因为不确定x是否在平衡树中, 那么先插入在查找可以防止这种情况的发生 
            {
                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;
    }
  • 相关阅读:
    ThinkPHP整合Kindeditor多图处理示例
    KindEditor用法介绍
    MySQL 1064 错误
    Nginx中虚拟主机与指定访问路径的设置方法讲解
    AJAX PHP无刷新form表单提交的简单实现(推荐)
    教PHP程序员如何找单位(全职+实习),超有用啊!
    利用正则表达式实现手机号码中间4位用星号(*)
    PHP项目做完后想上线怎么办,告诉你免费上线方法!
    备战NOIP——模板复习16
    备战NOIP——STL复习1
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/6881689.html
Copyright © 2011-2022 走看看