数组splay ------ luogu P3369 模板普通平衡树(Treap/SBT)

Posted ZlycerQan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组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\n", Splay_Tree.Find_x_rank (x));
        else if (type == 4)
            printf ("%d\n", Splay_Tree.Find_rank_x (x));
        else if (type == 5)
        {
            Splay_Tree.Insert (x);
            printf ("%d\n", Splay_Tree.Get_tree_value (Splay_Tree.Find_Prefix ()));
            Splay_Tree.Delete (x); 
        }
        else
        {
            Splay_Tree.Insert (x);
            printf ("%d\n", Splay_Tree.Get_tree_value (Splay_Tree.Find_Suffix ()));
            Splay_Tree.Delete (x);  
        }
    }
    
    return 0;
}

 

以上是关于数组splay ------ luogu P3369 模板普通平衡树(Treap/SBT)的主要内容,如果未能解决你的问题,请参考以下文章

[Splay]luogu P3391 文艺平衡树

[Luogu P4178]Tree (点分治+splay)

题解Luogu P1503 鬼子进村

Luogu1486郁闷的出纳员Splay

[LuoguP2161[ [SHOI2009]会场预约 (splay)

luogu3690