平衡树模板

Splay

仅支持构造、插入、查找、翻转。

#include 
#include 
#define R register
#define Null b
int n, m;
struct Data { int Key, Sum; bool rev; Data *Pre, *Son[2]; } b[100010], *root = b; int tot;
struct Splay_Tree
{
    void Pushup(R Data *Now){ Now->Sum = Now->Son[0]->Sum + Now->Son[1]->Sum + 1; }
    void Swap(R Data *&A, R Data *&B){ R Data *t = A; A = B; B = t; }
    void Pushdown(R Data *Now)
    {
        if(Now->rev)
        {
            Swap(Now->Son[0], Now->Son[1]); 
            Now->Son[0]->rev ^= 1, Now->Son[1]->rev ^= 1;
            Now->rev = 0;
        }
    }
    void Rotate(R Data *Now)
    {
        R bool d = (Now->Pre->Son[1] == Now);
        R Data *f = Now->Pre;
        f->Son[d] = Now->Son[!d];
        Now->Son[!d]->Pre = f;
        Now->Pre = f->Pre;
        f->Pre->Son[f->Pre->Son[1] == f] = Now;
        f->Pre = Now;
        Now->Son[!d] = f;
        Pushup(f);
    }
    void Preview(R Data *Now, R Data *Fa)
    {
        if(Now->Pre != Fa) Preview(Now->Pre, Fa);
        Pushdown(Now);
    }
    void Splay(R Data *Now, R Data *Fa = Null)
    {
        Preview(Now, Fa);
        while(Fa != Now->Pre)
        {
            if(Now->Pre->Pre != Fa)
                Rotate((Now->Pre->Pre->Son[0] == Now->Pre) ^ (Now->Pre->Son[0] == Now) ? Now : Now->Pre);
            Rotate(Now);

        }
        Pushup(Now);
        Fa == Null ? root = Now : 0;
    }
    void Insert(int x)
    {
        if(root == Null) b[++tot] = (Data) {x, 1, 0, Null, {Null, Null}}, root = b + tot;
        else
        {
            R Data *Now = root;
            while(Now != Null)
            {
                if(Now->Son[Now->Key < x] == Null) 
                {   
                    b[++tot] = (Data) {x, 1, 0, Now, {Null, Null}};
                    Now->Son[Now->Key < x] = b + tot;
                    break;
                }
                else Now = Now->Son[Now->Key < x];
            }
            Splay(Now);
        }
    }
    void Print(R Data *Now)
    {
        Pushdown(Now);
        if(Now->Son[0] != Null) Print(Now->Son[0]);
        printf("%d ", Now->Key);
        if(Now->Son[1] != Null) Print(Now->Son[1]);
    }
    Data* Select(R int K, R Data *Now = root)
    {
        Pushdown(Now);
        if(Now->Son[0]->Sum >= K) return Select(K, Now->Son[0]);
        else if(Now->Son[0]->Sum == K - 1) return Now;
        else return Select(K - Now->Son[0]->Sum - 1, Now->Son[1]);
    }
    void Reverse(R int l, R int r)
    {
        if(l - 1 == 0 && r + 1 > n) root->rev ^= 1;
        else if(l - 1 == 0) Splay(Select(r + 1)), root->Son[0]->rev ^= 1;
        else if(r + 1 > n) Splay(Select(l - 1)), root->Son[1]->rev ^= 1;
        else 
        {
            R Data *u = Select(l - 1), *v = Select(r + 1);
            Splay(u); Splay(v, u);
            root->Son[1]->Son[0]->rev ^= 1;
        }

    }
    Data* Build(R int begin, R int end)
    {
        if(begin > end) return Null;
        R int mid = begin + end >> 1;
        b[++tot] = (Data) {mid, 1, 0, Null, {Null, Null}};
        R Data *Now = b + tot;
        (Now->Son[1] = Build(mid + 1, end))->Pre = Now;
        (Now->Son[0] = Build(begin, mid - 1))->Pre = Now;
        Now->Sum += Now->Son[0]->Sum + Now->Son[1]->Sum;
        return Now;
    }
} a;
int main()
{
    b[0] = (Data) {0, 0, 0, Null, {Null, Null}};
    scanf("%d %d", &n, &m);
    root = a.Build(1, n);
    for(R int i = 1; i <= m; i++)
    {
        R int l, r;
        scanf("%d %d", &l, &r);
        a.Reverse(l, r);
    }
    a.Print(root);
    return 0;
}

Treap

非旋转,仅支持插入、删除、查找、翻转。

#include 
#include 
#include 
#define rand() (rand() ^ rand())
#define R register
#define Null b
int rnd(){
    unsigned x = rand();
    x = x << 15 ^ rand();
    x = x << 2 ^ rand();
    return x >> 1;
}
int n, m;
struct Data { int Key, Val, Sum; bool rev; Data *lson, *rson;} b[100010], *root = Null; int tot;
struct Treap
{
    void Swap(R Data *&A, R Data *&B) { R Data *t = A; A = B; B = t; }
    void Pushdown(R Data *Now)
    {
        if(Now->rev)
        {
            Swap(Now->lson, Now->rson);
            Now->lson->rev ^= 1; Now->rson->rev ^= 1;
            Now->rev = 0;
        }
    }
    void Pushup(R Data *Now){ Now->Sum = Now->lson->Sum + Now->rson->Sum + 1; }
    Data* Merge(R Data *A, R Data *B)
    {
        if(A == Null || B == Null) return A == Null ? B : A;
        Pushdown(A); Pushdown(B);
        if(A->Val > B->Val) A->rson = Merge(A->rson, B);
        else B->lson = Merge(A, B->lson);
        Pushup(A->Val > B->Val ? A : B);
        return A->Val > B->Val ? A : B;
    }
    void *Split(R Data *Now, R int K, R Data *&A, R Data *&B)
    {
        if(Now == Null) A = B = Null;
        else
        {
            Pushdown(Now);
            if(Now->lson->Sum >= K)
            {
                B = Now;
                Split(Now->lson, K, A, Now->lson);
            }
            else
            {
                A = Now;
                Split(Now->rson, K - Now->lson->Sum - 1, Now->rson, B);
            }
            Pushup(Now);
        }
    }
    void Insert(int x)
    {
        b[++tot] = (Data) {x, rnd(), 1, 0, Null, Null};
        root = Merge(root, b + tot);
    }
    void Reverse(int l, R int r)
    {
        R Data *A, *B, *C;
        if(l - 1 == 0 && r + 1 > n) root->rev ^= 1;
        else if(l - 1 == 0)
        {
            Split(root, r, A, B);
            A->rev ^= 1;
            root = Merge(A, B);
        } 
        else if(r + 1 > n)
        {
            Split(root, l - 1, A, B);
            B->rev ^= 1;
            root = Merge(A, B);
        }
        else
        {
            Split(root, l - 1, A, B);
            Split(B, r - l + 1, B, C);
            B->rev ^= 1;
            root = Merge(Merge(A, B), C);
        }
    }
    void Print(R Data *Now)
    {
        Pushdown(Now);
        if(Now->lson != Null) Print(Now->lson);
        printf("%d ", Now->Key);
        if(Now->rson != Null) Print(Now->rson);
    }
    Data* Build(R int begin, R int end, R int Id)
    {
        if(begin > end) return Null;
        R int mid = begin + end >> 1;
        b[++tot] = (Data) {mid, Id, 1, 0, Null, Null};
        R Data *Now = b + tot;
        Now->rson = Build(mid + 1, end, Id - 1);
        Now->lson = Build(begin, mid - 1, Id - 1);
        Now->Sum += Now->lson->Sum + Now->rson->Sum;
        return Now;
    }
} a;
int main()
{
    b[0] = (Data){0, 0, 0, 0, Null, Null};
    scanf("%d %d", &n, &m);
    root = a.Build(1, n, n);
    for(R int i = 1; i <= m; i++)
    {
        R int l, r;
        scanf("%d %d", &l, &r);
        a.Reverse(l, r);
    }
    a.Print(root);
    return 0;
}

你可能感兴趣的:(数据结构,#,平衡树,模板库,平衡树)