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

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

    闲的没事,把各种平衡树都写写

    比较比较。。。

    下面是替罪羊树

    #include <cstdio>
    #include <vector>
    
    #define Max_ 100010
    
    #define Inline __attri
    bute__( ( optimize( "-O2" ) ) )
    
    Inline void read (int &now)
    {
        register char word = getchar ();
        bool temp = false;
        for (now = 0; word < '0' || word > '9'; word = getchar ())
            if (word == '-')
                temp = true;
        for (; word >= '0' && word <= '9'; now = now * 10 + word - '0', word = getchar ());
        if (temp)    
            now = -now;
    }
    
    const double alpha = 0.63;
    
    int N;
    
    struct G_D
    {
        G_D *child[2];
        
        int key;
        int size, total;
        bool is_exist;
        
        inline void Up ()
        {
            this->size = this->child[0]->size + this->child[1]->size + is_exist;
            this->total = this->child[0]->total + this->child[1]->total + 1;
        }
        
        inline bool is_rebuild ()
        {
            return ((this->child[0]->total > this->total * alpha + 5) || (this->child[1]->total > this->total * alpha + 5));
        }
    };
    
    
    class Scapegoat_Tree_Type
    {
        
        private :
            
            G_D poor_mem[Max_];
            G_D *Root, *Tail, *null;
            
            G_D *reuse[Max_];
            int Reuse_top;
        
            Inline G_D *New_Node (int key)
            {
                G_D *now = Reuse_top ? reuse[-- Reuse_top] : Tail ++;
                now->child[0] = now->child[1] = null;
                now->size = now->total = 1;
                now->is_exist = true;
                now->key = key;
                return now;
            }
            
            Inline void Travel (G_D *now, std :: vector <G_D *> &line)
            {
                if (now == null)
                    return ;
                Travel (now->child[0], line);
                if (now->is_exist)
                    line.push_back (now);
                else
                    reuse[Reuse_top ++] = now;
                Travel (now->child[1], line);
            }
            
            Inline G_D *Divide (std :: vector <G_D *> &line, int l, int r)
            {
                if (l >= r)
                    return null;
                int Mid = (l + r) >> 1;
                G_D *now = line[Mid];
                now->child[0] = Divide (line, l, Mid);
                now->child[1] = Divide (line, Mid + 1, r);
                now->Up ();
                return now;
            }
            
            Inline void Re_Build (G_D *&now)
            {
                static std :: vector <G_D *> line;
                line.clear ();
                Travel (now, line);
                now = Divide (line, 0, line.size ());
            }
            
            Inline G_D **Insert (G_D *&now, int key)
            {
                if (now == null)
                {
                    now = New_Node (key);
                    return &null;
                }
                else
                {
                    now->size ++;
                    now->total ++;
                    G_D **res = Insert (now->child[key >= now->key], key);
                    if (now->is_rebuild ())
                        res = &now;
                    return res; 
                }
            }
            
            Inline void Erase (G_D *now, int pos)
            {
                now->size --;
                int res = now->child[0]->size + now->is_exist;
                if (now->is_exist && pos == res)
                {
                    now->is_exist = false;
                    return ;
                }
                else
                {
                    if (pos <= res)
                        Erase (now->child[0], pos);
                    else
                        Erase (now->child[1], pos - res);
                }
            }
            
        public :
            
            Scapegoat_Tree_Type ()
            {
                Tail = poor_mem;
                null = Tail ++;
                null->child[0] = null->child[1] = null;
                null->total = null->size = null->key = 0;
                
                Root = null;
                Reuse_top = 0;
            }
                   
            Inline void Insert (int key)
            {
                G_D **now = this->Insert (Root, key);
                if (*now != null)
                    Re_Build (*now);
            }
            
            Inline int Get_Rank (int key)
            {
                G_D *now = Root;
                register int Answer = 1;
                for (; now != null; )
                {
                    if (now->key >= key)
                        now = now->child[0];
                    else
                    {
                        Answer += now->child[0]->size + now->is_exist;
                        now = now->child[1];
                    }
                }
                return Answer;
            }
            
            Inline int Get_kth_number (int k)
            {
                int Count = 0;
                for (G_D *now = Root; now != null; )
                {
                    if (now->child[0]->size + 1 == k && now->is_exist)
                        return now->key;
                    else if (now->child[0]->size >= k)
                        now = now->child[0];
                    else
                    {
                        k -= now->child[0]->size + now->is_exist;
                        now = now->child[1];
                    }
                }
            }
            
            Inline  void Erase (int pos)
            {
                Erase (Root, Get_Rank (pos));
                if (Root->size < alpha * Root->total)
                    Re_Build (Root);
            }
          
    };
    
    Scapegoat_Tree_Type Tree;
    
    int M;
    int main (int argc, char *argv[])
    {
        
        read (M);
        
        for (int type, x; M --; )
        {
            read (type);
            read (x);
            
            switch (type)
            {
                case 1:
                    Tree.Insert (x);
                    break; 
                case 2:
                    Tree.Erase (x);
                    break;
                case 3:
                    printf ("%d
    ", Tree.Get_Rank (x));
                    break;
                case 4:
                    printf ("%d
    ", Tree.Get_kth_number (x));
                    break;
                case 5:
                    printf ("%d
    ", Tree.Get_kth_number (Tree.Get_Rank (x) - 1));
                    break;
                case 6:
                    printf ("%d
    ", Tree.Get_kth_number (Tree.Get_Rank (x + 1)));
                    break;
            }
        }
        
        return 0;
    }
  • 相关阅读:
    【报错问题】mysql无法使用别名查询
    【报错问题】java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode
    【源码】-springboot 启动后立马执行的方式
    【LINUX】$搭配使用的含义
    【JAVA】javaMail附件名超过60显示错误
    【Gradle】简单入门
    慢SQL案例之一
    【Flink】一. 什么是Flink?
    【spring基础】环境的搭建与后台
    [org.apache.common][打算学习开源工具包]
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7222906.html
Copyright © 2011-2022 走看看