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

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

近几天闲来无事。。。就把各种平衡树都写了一下。。。

下面是红黑树(Red Black Tree)

 

喜闻乐见拿到了luogu,COGS的rank1

QAQ rank1没啦!!!被树状数组艹啦!!!

 

 

 10.11 Updata 压了压行233333

 

#include <cstdio>
#include <iostream>
#define Max 100001
#define Red true
#define Black false
const int BUF = 100000100; char Buf[BUF], *buf = Buf;
#define rg register
#define Inline __attri\
bute__( ( optimize( "-O2" ) ) )
Inline void read (int &n)
{
    bool temp = false;
    for (n = 0; !isdigit (*buf); ++ buf) if (*buf == '-') temp = true;
    for (; isdigit (*buf); n = n * 10 + *buf - '0', ++ buf);
    if (temp) n = -n;
}
struct RD
{
    int v, _s, _w; bool _c; RD *f, *c[2];
    Inline void Fill (const int &_v, const bool &__c, const int &z, rg RD *n)
    { v = _v, _c = __c, _s = _w = z, f = c[0] = c[1] = n; }
    Inline void Up () { _s = c[0]->_s + c[1]->_s + _w; }
    Inline void dn ()
    { for (RD *n = this; n->_s; n = n->f) -- n->_s; }
    Inline int Get_Pos (const int &n) { return this->v == n ? -1 : n > v; } 
};
class Red_Black_Tree
{
    private : int _t; RD *Rt, *null, poor[Max], *Tail, *reuse[Max];
    private :
      
        Inline RD *New (const int &v)
        {
            rg RD *n = null;
            if (!_t) n = Tail ++; else n = reuse[-- _t];
            n->Fill (v, Red, 1, null);
            return n;
        }
        
        Inline void R (RD *&n, const bool &_p)
        {
            rg RD *C = n->c[_p ^ 1];
            n->c[_p ^ 1] = C->c[_p];
            if (C->c[_p]->_s) C->c[_p]->f = n;
            C->f = n->f; if (!n->f->_s) Rt = C;
            else  n->f->c[n->f->c[0] != n] = C;
            C->c[_p] = n; n->f = C; C->_s = n->_s; n->Up ();
        }
        
        Inline void If (rg RD *&n)
        {
            for (; n->f->_c; )
            {
                RD *_F = n->f, *_g = _F->f;
                bool _p = _F == _g->c[0]; RD *_u = _g->c[_p];
                if (_u->_c) _F->_c = _u->_c = Black, _g->_c = Red, n = _g;
                else if (n == _F->c[_p]) R (n = _F, _p ^ 1);
                else _g->_c = Red, _F->_c = Black, R (_g, _p);
            }
            Rt->_c = Black;
        }
        
        Inline RD *Find (RD *n, int v)
        {
            for (; n->_s && n->v != v; n = n->c[n->v < v]);
            return n;
        }
        
        Inline void Df (rg RD *&n)
        {
            for (; n != Rt && n->_c == Black; )
            {
                rg bool _p = n == n->f->c[0];
                RD *_F = n->f, *_u = _F->c[_p];
                if (_u->_c == Red)
                    _u->_c = Black, _F->_c = Red, R (n->f, _p ^ 1), _u = _F->c[_p];
                else if (_u->c[0]->_c == Black && _u->c[1]->_c == Black)
                    _u->_c = Red, n = _F;
                else
                {
                    if (_u->c[_p]->_c == Black)
                        _u->c[_p ^ 1]->_c = Black, _u->_c = Red, R (_u, _p), _u = _F->c[_p];
                    _u->_c = _F->_c, _u->c[_p]->_c = _F->_c = Black, R (_F, _p ^ 1);
                    break;
                }
            }
            n->_c = Black;
        }
        
    public :
        
        Red_Black_Tree ()
        {
            _t = 0, Tail = &poor[_t];
            null = Tail ++, null->Fill (0, Black, 0, NULL), Rt = null;
        }
        
        Inline void Insert (const int &v)
        {
            rg RD *n = Rt, *_F = null;
            rg int _p;
            for (; n->_s; n = n->c[_p])
            {
                ++ n->_s, _F = n, _p = n->Get_Pos (v);
                if (_p == -1) { ++ n->_w; return ; }
            }
            n = New (v); 
            if (_F->_s) _F->c[v > _F->v] = n; else Rt = n;
            n->f = _F; If (n); 
        }
        
        Inline void Delete (const int &v)
        {
            rg RD *_r = Find (Rt, v);
            if (!_r->_s) return ;
            if (_r->_w > 1) { -- _r->_w, _r->dn (); return ; }
            rg RD *_F = _r, *n = null;
            if (_r->c[0]->_s && _r->c[1]->_s)
                for (_F = _r->c[1]; _F->c[0]->_s; _F = _F->c[0]);
            n = _F->c[!_F->c[0]->_s], n->f = _F->f;
            if (!_F->f->_s) Rt = n;
            else _F->f->c[_F->f->c[1] == _F] = n;
            if (_r != _F) _r->v = _F->v, _r->_w = _F->_w;
            _F->f->dn ();
            for (RD *p = _F->f; _F->_w > 1 && p->_s && p != _r; p->_s -= _F->_w - 1, p = p->f);
            if (_F->_c == Black) Df (n);
            reuse[_t ++] = _F;
        }
        
        Inline int Get_kth_number (rg int k)
        {
            rg int _r; rg RD *n = Rt;
            for (; n->_s; )
            {
                _r = n->c[0]->_s;
                if (k <= _r) n = n->c[0];
                else if (_r + 1 <= k && k <= _r + n->_w) break;
                else k -= _r + n->_w, n = n->c[1];
            }
            return n->v;
        }
        
        Inline int Get_rank (const int &v)
        {
            rg int _r, cur = 0; rg RD *n = Rt;
            for (; n->_s; )
            {
                _r = n->c[0]->_s;
                if (n->v == v) break;
                else if (n->v > v) n = n->c[0];
                else cur += _r + n->_w, n = n->c[1];
            }
            return cur + _r + 1;
        }
        
        Inline int Find_Suffix (const int &v)
        {
            rg int _r = 0;
            for (RD *n = Rt; n->_s; )
                if (n->v > v) _r = n->v, n = n->c[0];
                else n = n->c[1];
            return _r;
        
        }
        
        Inline int Find_Prefix (const int &v)
        {
            rg int _r = 0;
            for (RD *n = Rt; n->_s; )
                if (n->v < v) _r = n->v, n = n->c[1];
                else n = n->c[0];
            return _r;
        }
};
Red_Black_Tree Rbt;
void write_ (int n)
{ if (n > 9) write_ (n / 10); putchar (n % 10 + '0'); }
inline void write (int n)
{
    if (n < 0) putchar ('-'), n = -n;
    write_ (n); putchar ('\n');
}
int Main ()
{
    fread (buf, 1, BUF, stdin); int N; read (N);
    for (int type, x; N --; )
    {
        read (type); read (x);
           if (type == 1) Rbt.Insert (x);
        else if (type == 2) Rbt.Delete (x);
        else if (type == 3) write (Rbt.Get_rank (x));
        else if (type == 4) write (Rbt.Get_kth_number (x));
        else if (type == 5) write (Rbt.Find_Prefix (x));
        else write (Rbt.Find_Suffix (x));
    }
    return 0;
}
int ZlycerQan = Main(); int main(int argc, char *argv[]){;}

 

 

 

 

#include <cstdio>
#include <iostream>
 
#define Max 100001
 
#define Red true
#define Black false
 
const int BUF = 100000100;
char Buf[BUF], *buf = Buf;
 
#define Inline __attri\
bute__( ( optimize( "-O2" ) ) )
Inline void read (int &now)
{
    int temp = 0;
    for (now = 0; !isdigit (*buf); ++ buf)
        if (*buf == '-')
            temp = 1;
    for (; isdigit (*buf); now = now * 10 + *buf - '0', ++ buf);
    if (temp)    
        now = -now;
}
 
struct R_D
{
    int key, size, weigth;
    bool color;
    
    R_D *father, *child[2];
    
    Inline void Fill (const int &__key, const bool &__color, const int &z, register R_D *now)
    {
        this->key = __key;
        this->color = __color;
        this->size = this->weigth = z;
        
        this->father = this->child[0] = this->child[1] = now;
    }
    
    Inline void Up ()
    {
        this->size = this->child[0]->size + this->child[1]->size + this->weigth;
    }
    
    Inline void Down ()
    {
        for (R_D *now = this; now->size; now = now->father)
            now->size --;
    }
    
    Inline int Get_Pos (const int &now) const
    {
        return this->key == now ? -1 : now > this->key;
    } 
};
 
 
class Red_Black_Tree
{
    
    private :
        
        int Top;
        
        R_D *Root, *null;
        R_D poor[Max], *Tail, *reuse[Max];
        
        
        Inline R_D *New (const int &key)
        {
            register R_D *now = null;
            if (!Top)
                now = Tail ++;
            else
                now = reuse[-- Top];
            now->Fill (key, Red, 1, null);
            return now;
        }
        
        Inline void Rotate (R_D *&now, const bool &pos)
        {
            register R_D *C = now->child[pos ^ 1];
            now->child[pos ^ 1] = C->child[pos];
            if (C->child[pos]->size)
                C->child[pos]->father = now;
            C->father = now->father;
            if (!now->father->size)
                Root = C;
            else 
                now->father->child[now->father->child[0] != now] = C;
            C->child[pos] = now;
            now->father = C;
            C->size = now->size;
            now->Up ();
        }
        
        Inline void Insert_Fill (register R_D *&now)
        {
            for (; now->father->color; )
            {
                R_D *Father = now->father, *Grand = Father->father;
                bool pos = Father == Grand->child[0];
                R_D *Uncle = Grand->child[pos];
                if (Uncle->color)
                {
                    Father->color = Uncle->color = Black;
                    Grand->color = Red;
                    now = Grand;
                }
                else if (now == Father->child[pos])
                    Rotate (now = Father, pos ^ 1);
                else
                {
                    Grand->color = Red;
                    Father->color = Black;
                    Rotate (Grand, pos);
                }
            }
            Root->color = Black;
        }
        
        Inline R_D *Find (R_D *now, int key)
        {
            for (; now->size && now->key != key; now = now->child[now->key < key]);
            return now;
        }
        
        Inline void Delete_Fill (register R_D *&now)
        {
            for (; now != Root && now->color == Black; )
            {
                register bool pos = now == now->father->child[0];
                R_D *Father = now->father, *Uncle = Father->child[pos];
                if (Uncle->color == Red)
                {
                    Uncle->color = Black;
                    Father->color = Red;
                    Rotate (now->father, pos ^ 1);
                    Uncle = Father->child[pos];
                }
                else if (Uncle->child[0]->color == Black && Uncle->child[1]->color == Black)
                {
                    Uncle->color = Red;
                    now = Father;
                }
                else
                {
                    if (Uncle->child[pos]->color == Black)
                    {
                        Uncle->child[pos ^ 1]->color = Black;
                        Uncle->color = Red;
                        Rotate (Uncle, pos);
                        Uncle = Father->child[pos];
                    }
                    Uncle->color = Father->color;
                    Uncle->child[pos]->color = Father->color = Black;
                    Rotate (Father, pos ^ 1);
                    break;
                }
            }
            now->color = Black;
        }
        
    public :
        
        Red_Black_Tree ()
        {
            Top = 0;
            Tail = &poor[Top];
            null = Tail ++;
            null->Fill (0, Black, 0, NULL);
            Root = null;
        }
        
        Inline void Insert (const int &key)
        {
            register R_D *now = Root, *Father = null;
            register int pos;
            for (; now->size; now = now->child[pos])
            {
                now->size ++;
                Father = now;
                pos = now->Get_Pos (key);
                if (pos == -1)
                {
                    now->weigth ++;
                    return ;
                }
            }
            now = New (key);
            if (Father->size)
                Father->child[key > Father->key] = now;
            else
                Root = now;
            now->father = Father;
            this->Insert_Fill (now); 
        }
        
        Inline void Delete (const int &key)
        {
            register R_D *res = Find (Root, key);
            if (!res->size)
                return ;
            if (res->weigth > 1)
            {
                res->weigth --;
                res->Down ();
                return ;
            }
            register R_D *Father = res, *now = null;
            
            if (res->child[0]->size && res->child[1]->size)
                for (Father = res->child[1]; Father->child[0]->size; Father = Father->child[0]);
            
            now = Father->child[!Father->child[0]->size];
            now->father = Father->father;
            if (!Father->father->size)
                Root = now;
            else
                Father->father->child[Father->father->child[1] == Father] = now;
            
            if (res != Father)
            {
                res->key = Father->key;
                res->weigth = Father->weigth;
            }
            
            Father->father->Down ();
    
            for (R_D *Fuck = Father->father; Father->weigth > 1 && Fuck->size && Fuck != res; Fuck->size -= Father->weigth - 1, Fuck = Fuck->father);
    
            if (Father->color == Black)
                Delete_Fill (now);
            
            reuse[Top ++] = Father;
        }
        
        Inline int Get_kth_number (register int k)
        {
            register int res;
            register R_D *now = Root;
            
            for (; now->size; )
            {
                res = now->child[0]->size;
                
                if (k <= res)
                    now = now->child[0];
                else if (res + 1 <= k && k <= res + now->weigth)
                    break;
                else 
                {
                    k -= res + now->weigth;
                    now = now->child[1];
                }
            }
            return now->key;
        }
        
        Inline int Get_rank (const int &key)
        {
            register int res, cur = 0;
            register R_D *now = Root;
            
            for (; now->size; )
            {
                res = now->child[0]->size;
                if (now->key == key)
                    break;
                else if (now->key > key)
                    now = now->child[0];
                else
                {
                    cur += res + now->weigth;
                    now = now->child[1];
                }
            }
            
            return cur + res + 1;
        }
        
        Inline int Find_Suffix (const int &key)
        {
            register int res = 0;
            
            for (R_D *now = Root; now->size; )
                if (now->key > key)
                {
                    res = now->key;
                    now = now->child[0];
                }
                else 
                    now = now->child[1];
            
            return res;
        
        }
        
        Inline int Find_Prefix (const int &key)
        {
            register int res = 0;
            
            for (R_D *now = Root; now->size; )
                if (now->key < key)
                {
                    res = now->key;
                    now = now->child[1];
                }
                else
                    now = now->child[0];
            return res;
        }
};
 
Red_Black_Tree Rbt;

void write_ (int now)
{
    if (now > 9)
        write_ (now / 10);
    putchar (now % 10 + '0');
}

inline void write (int now)
{
    if (now < 0) putchar ('-'), now = -now;
    write_ (now);
    putchar ('\n');
}


int N;
 
int Main ()
{
    fread (buf, 1, BUF, stdin);
    read (N);
    
    for (int type, x; N --; )
    {
        read (type);
        read (x);
        
        switch (type)
        {
            case 1:
                Rbt.Insert (x);
                break;
            case 2:
                Rbt.Delete (x);
                break;
            case 3:
                write (Rbt.Get_rank (x));
                break;  
            case 4:
                write (Rbt.Get_kth_number (x));
                break;
            case 5:
                write (Rbt.Find_Prefix (x));
                break;
            case 6:
                write (Rbt.Find_Suffix (x));
                break;
        }
    }
    
    return 0;
}
int ZlycerQan = Main();
int main(int argc, char *argv[]){;}

 

posted @ 2017-07-22 19:31  ZlycerQan  阅读(734)  评论(1编辑  收藏  举报