fhq treap ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

二次联通门 : LibreOJ #104. 普通平衡树

 

 

 

 

#include <cstdio>
#include <iostream>
#include <algorithm>
const int BUF = 12312323;
char Buf[BUF], *buf = Buf;

inline void read (int &now)
{
    bool temp = false;
    for (now = 0; !isdigit (*buf); ++ buf)
        if (*buf == '-') temp = true;
    for (; isdigit (*buf); now = now *10 + *buf - '0', ++ buf);
    if (temp) now = -now;
}

struct T_D
{
    T_D *L, *R;
    int key, r, s;
    inline void Updata ()
    {
        s = 1 + (L ? L->s : 0) + (R ? R->s : 0);
    }
};

#define Max 1231231
struct D
{    
    T_D *x, *y; D () {}
    D (T_D *_x, T_D *_y) : x (_x), y (_y) {}
};
class Fhq_Treap
{
    private :
        
        T_D poor[Max], *Ta, *Root;
        
        inline T_D *New (int _x)
        {
            T_D *now = ++ Ta;
            now->r = rand (), now->key = _x;
            now->s = 1, now->L = now->R = NULL;
            return now;    
        }
        
        D Split (T_D *now, int k)
        {
            if (now == NULL) return D (NULL, NULL);
            D res;
            if ((now->L ? now->L->s : 0) >= k)
            {
                res = Split (now->L, k);
                now->L = res.y, now->Updata ();
                res.y = now;
            }
            else
            {
                res = Split (now->R, k - (now->L ? now->L->s : 0) - 1);
                now->R = res.x, now->Updata ();
                res.x = now;
            }
            return res;
        }
        
        T_D *Merge (T_D *A, T_D *B)
        {
            if (A == NULL) return B;
            if (B == NULL) return A;
            if (A->r < B->r)
            {
                A->R = Merge (A->R, B);
                A->Updata (); return A;
            }
            else 
            {
                B->L = Merge (A, B->L);    
                B->Updata (); return B;
            }
        }

        int Get_rank (T_D *now, int k)
        {
            if (now == NULL) return 0;
            return k <= now->key ? Get_rank (now->L, k) : (Get_rank (now->R, k) + (now->L ? now->L->s : 0) + 1);
        }

    public :
        
        Fhq_Treap () { Ta = poor; }
        inline int Get_rank (int k)
        {
            return Get_rank (Root, k) + 1;
        }

        int Find_kth (int k)
        {
            D x = Split (Root, k - 1);
            D y = Split (x.y, 1);
            T_D *res = y.x;
            Root = Merge (Merge (x.x, res), y.y);
            return res->key;
        }

        void Insert (int key)
        {
            int k = Get_rank (Root, key);
            D x = Split (Root, k);
            T_D *now = New (key);
            Root = Merge (Merge (x.x, now), x.y);
        }

        void Delete (int key)
        {
            int k = Get_rank (Root, key);
            D x = Split (Root, k);
            D y = Split (x.y, 1);
            Root = Merge (x.x, y.y);
        }

        int Find_Pre (int key)
        {
            int k = Get_rank (Root, key);
            D x = Split (Root, k - 1);
            D y = Split (x.y, 1);
            T_D *res = y.x;
            Root = Merge (Merge (x.x, res), y.y);
            return res->key;
        }

        int Find_Suc (int key)
        {
            int k = Get_rank (Root, key + 1);
            D x = Split (Root, k);
            D y = Split (x.y, 1);
            T_D *res = y.x;
            Root = Merge (Merge (x.x, res),  y.y);
            return res->key;
        }
};

Fhq_Treap Tree;
int Main ()
{
    fread (buf, 1, BUF, stdin);
    int N, M; register int i;
    read (N); int x, type;
    for (i = 1; i <= N; ++ i)
    {
        read (type), read (x);
         if (type == 1)
            Tree.Insert (x);
        else if (type == 2)
            Tree.Delete (x);
        else if (type == 3)
            printf ("%d\n", Tree.Get_rank (x));
        else if (type == 4)
            printf ("%d\n", Tree.Find_kth (x));
        else if (type == 5)
            printf ("%d\n", Tree.Find_Pre (x));
        else printf ("%d\n", Tree.Find_Suc (x));
    }
    return 0;
}

int ZlycerQan = Main ();
int main (int argc, char *argv[]) {;}

 

posted @ 2017-08-25 10:07  ZlycerQan  阅读(257)  评论(0编辑  收藏  举报