首页 > 代码库 > 替罪羊树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

替罪羊树 ------ 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\n", Tree.Get_Rank (x));
                break;
            case 4:
                printf ("%d\n", Tree.Get_kth_number (x));
                break;
            case 5:
                printf ("%d\n", Tree.Get_kth_number (Tree.Get_Rank (x) - 1));
                break;
            case 6:
                printf ("%d\n", Tree.Get_kth_number (Tree.Get_Rank (x + 1)));
                break;
        }
    }
    
    return 0;
}

 

替罪羊树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)