带模板的基于 SBT 的名次树

来源:互联网 发布:黑莓 转制软件 编辑:程序博客网 时间:2024/06/01 09:30

注:以下模板仅供参考,经测试发现效率有时不及 Treap,待改进!

template<typename T>class SBT{    struct Node    {        T v;        INT s;        Node* ch[2];        Node() : v(), s(), ch() {}        Node(const T& v) : v(v), s(), ch() {}        void maintain()        {            s = ch[0]->s + ch[1]->s + 1;        }        INT comp(const T& x) const        {            if (!(v < x) && !(x < v)) return -1;            return v < x;        }        INT compRank(INT k) const        {            if (ch[0]->s + 1 == k) return -1;            return ch[0]->s + 1 < k;        }    };    Node* null;    Node* root;public:    SBT()    {        null = new Node;        root = null->ch[0] = null->ch[1] = null;    }    ~SBT()    {        clear();        delete null;    }private:    void clear(Node* &r)    {        if (r == null) return;        clear(r->ch[0]);        clear(r->ch[1]);        delete r;    }public:    void clear() { clear(root); }private:    void rotate(Node* &r, INT d)    {        Node* k = r->ch[d ^ 1];        r->ch[d ^ 1] = k->ch[d];        k->ch[d] = r;        r->maintain();        k->maintain();        r = k;    }private:    void adjust(Node* &r, INT d)    {        if (r->ch[d] == null) return;        else if (r->ch[d]->ch[d]->s > r->ch[d ^ 1]->s)            rotate(r, d ^ 1);        else if (r->ch[d]->ch[d ^ 1]->s > r->ch[d ^ 1]->s)        {            rotate(r->ch[d], d);            rotate(r, d ^ 1);        }        else return;        adjust(r->ch[0], 0);        adjust(r->ch[1], 1);        adjust(r, 0);        adjust(r, 1);    }private:    void insert(Node* &r, const T& x)    {        if (r == null)        {            r = new Node(x);            r->ch[0] = r->ch[1] = null;            r->maintain();            return;        }        INT d = r->comp(x);        if (d == -1) return;        insert(r->ch[d], x);        r->maintain();        adjust(r, d);    }public:    void insert(const T x) { insert(root, x); }private:    bool count(Node* r, const T& x) const    {        if (r == null)            return false;        INT d = r->comp(x);        if (d == -1) return true;        return count(r->ch[d], x);    }public:    bool count(const T x) const { return count(root, x); }public:    INT size() const { return root->s; }private:    void deleteNode(Node* &r)    {        Node* parent = r;        Node* left = r->ch[0];        while (left->ch[1] != null)        {            left->s--;            parent = left;            left = left->ch[1];        }        parent->ch[parent != r] = left->ch[0];        r->v = left->v;        delete left;    }    void erase(Node* &r, const T& x)    {        if (r == null)            return;        INT d = r->comp(x);        if (d == -1)        {            if (r->ch[0] == null || r->ch[0] == null)            {                Node* k;                if (r->ch[0] != null) k = r->ch[0];                else k = r->ch[1];                delete r;                r = k;            }            else            {                deleteNode(r);                r->maintain();            }            return;        }        else            erase(r->ch[d], x);        r->maintain();    }public:    void erase(const T x) { erase(root, x); }private:    INT rank(Node* r, const T& x, INT k) const    {        if (r == null)            return 0;        INT d = r->comp(x);        if (d == -1)            return k + r->ch[0]->s + 1;        return rank(r->ch[d], x, k + d * (r->ch[0]->s + 1));    }public:    INT rank(const T x) const { return rank(root, x, 0); }private:    const T& kth(Node* r, INT k)    {        INT d = r->compRank(k);        if (d == -1)            return r->v;        return kth(r->ch[d], k - d * (r->ch[0]->s + 1));    }public:    bool kth(INT k, T& ans)    {        if (!(0 < k && k <= root->s)) return false;        ans = kth(root, k);        return true;    }};
原创粉丝点击