平衡树模板

来源:互联网 发布:微博怎么认证淘宝卖家 编辑:程序博客网 时间:2024/06/06 00:50

Splay

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

#include <cstdio>#include <cstring>#define R register#define Null bint 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 <cstdio>#include <cstring>#include <cstdlib>#define rand() (rand() ^ rand())#define R register#define Null bint 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;}
原创粉丝点击