multi_treap

来源:互联网 发布:win10好软件 编辑:程序博客网 时间:2024/06/05 11:34
#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;class multi_treap//multi_treap和treap类似,也是一种排序二叉树,但支持重复元素,其他功能上和treap一样{private:struct node//multi_treap的节点定义{node* ch[2];int v, r, s, num;int cmp(int x){if (x == v) return -1;return(x < v ? 0 : 1);}};node *root;//multi_treap的根void updata(node* o){if (!o) return;o->s = o->num;if (o->ch[0]) o->s += o->ch[0]->s;if (o->ch[1]) o->s += o->ch[1]->s;}void rateto(node* &o, int d){node* k;k = o->ch[d ^ 1];o->ch[d ^ 1] = k->ch[d];k->ch[d] = o;updata(o);updata(k);o = k;}void add(node* &o, int x){if (!o){o = new node();o->ch[0] = o->ch[1] = 0;o->v = x;o->r = rand()*rand();o->s = 1;o->num = 1;return;}int d = o->cmp(x);if (d == -1){o->num++;//multi的开关,注释掉可以关闭multi功能o->s++;}else{add(o->ch[d], x);updata(o);if (o->r < o->ch[d]->r) rateto(o, d ^ 1);}}void remove(node* &o, int x){int d = o->cmp(x);if (d == -1){if (o->num>1){o->num--;o->s--;}else{if (!(o->ch[0])){node *p = o;o = o->ch[1];free(p);p = 0;}else if (!(o->ch[1])){node *p = o;o = o->ch[0];free(p);p = 0;}else{int d2 = o->ch[0]->r > o->ch[1]->r ? 1 : 0;rateto(o, d2);remove(o->ch[d2], x);}}}else remove(o->ch[d], x);updata(o);}int left(node* o){if (o->ch[0]) return o->ch[0]->s;else return 0;}int Kth(int k){node *p = root;while (1){int su = (p->ch[0] ? p->ch[0]->s : 0);if (su + 1 <= k&&k <= su + p->num) return p->v;else if (k <= su) p = p->ch[0];else{k -= su + p->num;p = p->ch[1];}}}int Rank(int x){int ans = 0;node *p = root;while (p){if (p->v == x){ans += 1 + (p->ch[0] ? p->ch[0]->s : 0);return ans;}elseif (x < p->v) p = p->ch[0];else{ans += p->num + (p->ch[0] ? p->ch[0]->s : 0);p = p->ch[1];}}return ans+1;}int RankPlus(int x){    int ans = 0;node *p = root;while (p){if (p->v == x){ans += p->num + (p->ch[0] ? p->ch[0]->s : 0);return ans;}elseif (x < p->v) p = p->ch[0];else{ans += p->num + (p->ch[0] ? p->ch[0]->s : 0);p = p->ch[1];}}return ans;}int Suc(int x){node* p = root;int ans = 0;bool find = 0;while (p){if (p->v > x){ans = p->v;find = 1;}p = p->ch[p->v <= x];}if (find) return ans;else return -1;}int Pre(int x){node *p = root;int ans = 0;bool find = 0;while (p){if (p->v < x){ans = p->v;find = 1;}p = p->ch[p->v < x];}if (find) return ans;else return -1;}bool Find(node* o, int x){while (o){int d = o->cmp(x);if (d == -1) return 1;else o = o->ch[d];}return 0;}void mymemory(node* &o){if (!o) return;if (o->ch[0]) mymemory(o->ch[0]);if (o->ch[1]) mymemory(o->ch[1]);free(o);o = 0;}//以上是multi_treap的实现部分public:int size() //返回multi_treap中元素的个数{if (root) return root->s;else return 0;}void insert(int x)//在multi_treap中插入一个x{add(root, x);}void erase(int x)//删除multi_treap中的元素x,如果multi_treap中x的有多个,则只删除一个{remove(root, x);}int kth(int x) //返回multi_treap中排名为x的元素的值,如果x非法,则返回-1{if (x <= 0 || x > size()) return -1;else return Kth(x);}int rank(int x) //返回x在multi_treap中的排名,如果x没有在multi_treap中,则返回-1{return Rank(x);}int suc(int x) //返回multi_treap中大于x的第一个元素的值(后驱),如果x大于等于multi_treap中的最大值,则返回-1{return Suc(x);}int pre(int x) //返回multi_treap中小于x的第一个元素的值(前驱),如果x小于等于multi_treap中的最小值,则返回-1{return Pre(x);}bool find(int x) //返回x是否在该multi_treap{return Find(root, x);}void clear() //清空multi_treap{mymemory(root);}multi_treap() //multi_treap初始化{root = 0;}int rankplus(int x){    return RankPlus(x);}};
版权来至于上决。

0 0
原创粉丝点击