Treap

从 Trac 迁移的文章

这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。

原文章内容如下:

{{{
// 不带size域的treap
class Treap {
public:
    const static int MaxN = 100000;
    int root, tsize, l[MaxN], r[MaxN], p[MaxN];
    int key[MaxN];

    void rot_l(int &x) {    //before using this function, please ensure that the right son of x exist
        int tmp = r[x];
        r[x] = l[tmp]; l[tmp] = x;
        x = tmp;
    }
    void rot_r(int &x) {    //before using this function, please ensure that the left son of x exist
        int tmp = l[x];
        l[x] = r[tmp]; r[tmp] = x;
        x = tmp;
    }
    Treap():root(-1),tsize(-1) {}
    void insert(int &root, const int &x) {
        if(root == -1) {
            key[++tsize] = x;
            root = tsize;
            p[root] = rand();
            l[root] = r[root] = -1;
        }
        else if(x <= key[root]) {
            insert(l[root], x);
            if(p[l[root]] > p[root])  rot_r(root);
        }
        else {
            insert(r[root], x);
            if(p[r[root]] > p[root])  rot_l(root);
        }
    }
    void del(int &root, const int &x) {
        if(key[root] == x) {
            if(l[root]==-1 && r[root]==-1)  root = -1;
            else if(l[root] == -1)  root = r[root];
            else if(r[root] == -1)  root = l[root];
            else {
                if(p[l[root]] > p[r[root]]) {
                    rot_r(root);
                    del(r[root], x);
                }
                else {
                    rot_l(root);
                    del(l[root], x);
                }
            }
        }
        else if(x < key[root])  del(l[root], x);
        else del(r[root], x);
    }
    bool find(int &root, const int &x) {
        if(root == -1)  return  false;
        if(x == key[root])  return  true;
        else if(x < key[root])  return  find(l[root], x);
        else return  find(r[root], x);
    }
};

18. 带size域的treap
//带size的treap
class Treap {
public:
    const static int MaxN = 100000;
    int root, tsize, l[MaxN], r[MaxN], p[MaxN], nsize[MaxN];
    int key[MaxN];

    void maintain(const int &root) {
        int ta, tb;
        ta = l[root]==-1? 0 : nsize[l[root]];
        tb = r[root]==-1? 0 : nsize[r[root]];
        nsize[root] = ta+tb+1;
    }
    void rot_l(int &x) {    //before using this function, please ensure that the right son of x exist
        int tmp = r[x];
        r[x] = l[tmp]; maintain(x);
        l[tmp] = x; x = tmp; maintain(x);
    }
    void rot_r(int &x) {    //before using this function, please ensure that the left son of x exist
        int tmp = l[x];
        l[x] = r[tmp]; maintain(x);
        r[tmp] = x; x = tmp; maintain(x);
    }
    Treap():root(-1),tsize(-1) {}
    void insert(int &root, const int &x) {
        if(root == -1) {
            key[++tsize] = x;
            root = tsize;
            p[root] = rand();
            l[root] = r[root] = -1;
            nsize[root] = 1;
        }
        else if(x <= key[root]) {
            insert(l[root], x);
            if(p[l[root]] > p[root])  rot_r(root);
        }
        else {
            insert(r[root], x);
            if(p[r[root]] > p[root])  rot_l(root);
        }
        maintain(root);
    }
    void del(int &root, const int &x) {
        if(key[root] == x) {
            if(l[root]==-1 && r[root]==-1)  root = -1;
            else if(l[root] == -1)  root = r[root];
            else if(r[root] == -1)  root = l[root];
            else {
                if(p[l[root]] > p[r[root]]) {
                    rot_r(root);
                    del(r[root], x);
                }
                else {
                    rot_l(root);
                    del(l[root], x);
                }
            }
        }
        else if(x < key[root])  del(l[root], x);
        else del(r[root], x);
        if(root != -1)  maintain(root);
    }
    int kthElement(const int &root, int k) {
        int ta;
        ta = l[root]==-1? 0 : nsize[l[root]];
        if(ta >= k)  return  kthElement(l[root], k);
        else if(ta+1 == k)  return  key[root];
        else  return  kthElement(r[root], k-ta-1);
    }
    bool find(int &root, const int &x) {
        if(root == -1)  return  false;
        if(x == key[root])  return  true;
        else if(x < key[root])  return  find(l[root], x);
        else return  find(r[root], x);
    }
};
}}}
// 不带size域的treap
class Treap {
public:
    const static int MaxN = 100000;
    int root, tsize, l[MaxN], r[MaxN], p[MaxN];
    int key[MaxN];
    void rot_l(int &x) {    //before using this function, please ensure that the right son of x exist
        int tmp = r[x];
        r[x] = l[tmp]; l[tmp] = x;
        x = tmp;
    }
    void rot_r(int &x) {    //before using this function, please ensure that the left son of x exist
        int tmp = l[x];
        l[x] = r[tmp]; r[tmp] = x;
        x = tmp;
    }
    Treap():root(-1),tsize(-1) {}
    void insert(int &root, const int &x) {
        if(root == -1) {
            key[++tsize] = x;
            root = tsize;
            p[root] = rand();
            l[root] = r[root] = -1;
        }
        else if(x <= key[root]) {
            insert(l[root], x);
            if(p[l[root]] > p[root])  rot_r(root);
        }
        else {
            insert(r[root], x);
            if(p[r[root]] > p[root])  rot_l(root);
        }
    }
    void del(int &root, const int &x) {
        if(key[root] == x) {
            if(l[root]==-1 && r[root]==-1)  root = -1;
            else if(l[root] == -1)  root = r[root];
            else if(r[root] == -1)  root = l[root];
            else {
                if(p[l[root]] > p[r[root]]) {
                    rot_r(root);
                    del(r[root], x);
                }
                else {
                    rot_l(root);
                    del(l[root], x);
                }
            }
        }
        else if(x < key[root])  del(l[root], x);
        else del(r[root], x);
    }
    bool find(int &root, const int &x) {
        if(root == -1)  return  false;
        if(x == key[root])  return  true;
        else if(x < key[root])  return  find(l[root], x);
        else return  find(r[root], x);
    }
};
18. 带size域的treap
//带size的treap
class Treap {
public:
    const static int MaxN = 100000;
    int root, tsize, l[MaxN], r[MaxN], p[MaxN], nsize[MaxN];
    int key[MaxN];
    void maintain(const int &root) {
        int ta, tb;
        ta = l[root]==-1? 0 : nsize[l[root]];
        tb = r[root]==-1? 0 : nsize[r[root]];
        nsize[root] = ta+tb+1;
    }
    void rot_l(int &x) {    //before using this function, please ensure that the right son of x exist
        int tmp = r[x];
        r[x] = l[tmp]; maintain(x);
        l[tmp] = x; x = tmp; maintain(x);
    }
    void rot_r(int &x) {    //before using this function, please ensure that the left son of x exist
        int tmp = l[x];
        l[x] = r[tmp]; maintain(x);
        r[tmp] = x; x = tmp; maintain(x);
    }
    Treap():root(-1),tsize(-1) {}
    void insert(int &root, const int &x) {
        if(root == -1) {
            key[++tsize] = x;
            root = tsize;
            p[root] = rand();
            l[root] = r[root] = -1;
            nsize[root] = 1;
        }
        else if(x <= key[root]) {
            insert(l[root], x);
            if(p[l[root]] > p[root])  rot_r(root);
        }
        else {
            insert(r[root], x);
            if(p[r[root]] > p[root])  rot_l(root);
        }
        maintain(root);
    }
    void del(int &root, const int &x) {
        if(key[root] == x) {
            if(l[root]==-1 && r[root]==-1)  root = -1;
            else if(l[root] == -1)  root = r[root];
            else if(r[root] == -1)  root = l[root];
            else {
                if(p[l[root]] > p[r[root]]) {
                    rot_r(root);
                    del(r[root], x);
                }
                else {
                    rot_l(root);
                    del(l[root], x);
                }
            }
        }
        else if(x < key[root])  del(l[root], x);
        else del(r[root], x);
        if(root != -1)  maintain(root);
    }
    int kthElement(const int &root, int k) {
        int ta;
        ta = l[root]==-1? 0 : nsize[l[root]];
        if(ta >= k)  return  kthElement(l[root], k);
        else if(ta+1 == k)  return  key[root];
        else  return  kthElement(r[root], k-ta-1);
    }
    bool find(int &root, const int &x) {
        if(root == -1)  return  false;
        if(x == key[root])  return  true;
        else if(x < key[root])  return  find(l[root], x);
        else return  find(r[root], x);
    }
};