treap60分求助

P3369 【模板】普通平衡树

可能有重复数字的,这个比较复杂,你这样不一定,要加一个函数统计重复个数 我把我的代码给你看下
by cmll02 @ 2020-01-16 22:33:12


```cpp #include <stdio.h> #include <string.h> inline long long read() { long long num = 0; int f = 1; char c = getchar(); while (c < 48 || c > 57) { if (c == '-')f = -1; c = getchar(); } while (c >= 48 && c <= 57) num = (num << 3) + (num << 1) + (c ^ 48), c = getchar(); return num*f; } #include <time.h> #include <stdlib.h> int rrnk, lrnk; template<typename T = int> class Treap { public: struct Node{ Node *ch[2]; //左右子树 int r; //优先级。数值越大,优先级越高 T v; int s; int cmp(T x)const { if (x == v) return -1; return x < v ? 0 : 1; } int Cmp(T z) { if (z == s)return -1; return z < s ? 0 : 1; } void maintain() { s = 1; if (ch[0])s += ch[0]->s; if (ch[1])s += ch[1]->s; } }; protected: int samenumber(Node *o, T x) { if (!o)return 0; if (o->v != x) { if (o->v>x) { return samenumber(o->ch[0], x); } else { return samenumber(o->ch[1], x); } } return 1 + samenumber(o->ch[0], x) + samenumber(o->ch[1], x); } int find(Node *o, T x){ int p = 0; while (o != NULL){ int d = o->cmp(x); if (d == -1) return p + (o->ch[1] ? o->ch[1]->s + 1 : 1) + 0 * ((rrnk = samenumber(o->ch[1], x)) + (lrnk = samenumber(o->ch[0], x))); //存在 else p += (d ? 0 : (o->ch[1] ? o->ch[1]->s + 1 : 1)), o = o->ch[d]; } return 0; //不存在 } //d=0代表左旋,d=1代表右旋 void rotate(Node* &o, int d){ Node *k = o->ch[d ^ 1]; o->ch[d ^ 1] = k->ch[d]; k->ch[d] = o; o->maintain(); k->maintain(); o = k; } //在以o为根的子树中插入键值x,修改o void Insert(Node* &o, T x){ if (o == NULL) { o = new Node(); o->ch[0] = o->ch[1] = NULL; o->v = x; o->r = rand(); } else { //int d = (x<o->v ? 0 : 1); int d = (x<o->v ? 0 : 1); Insert(o->ch[d], x); if (o->ch[d]->r > o->r) rotate(o, d ^ 1); } if (o) o->maintain(); }; void Remove(Node* &o, T x){ int d = o->cmp(x); if (d == -1){ Node *u = o; if (o->ch[0] == NULL) { o = o->ch[1]; delete u; } else if (o->ch[1] == NULL) { o = o->ch[0]; delete u; } else{ int d2 = (o->ch[0]->r>o->ch[1]->r ? 1 : 0); rotate(o, d2); Remove(o->ch[d2], x); } } else Remove(o->ch[d], x); if (o) o->maintain(); } public: static const T _TREAP_ERROR_404_NOT_FOUND = ((T)(0x1f2e3d4c)); protected: T FindKth(Node *&o, int k) { if (k<1 || k>o->s)return _TREAP_ERROR_404_NOT_FOUND; int s = o->ch[1] ? o->ch[1]->s : 0; if (k <= s)return FindKth(o->ch[1], k); if (k == s + 1)return o->v; return FindKth(o->ch[0], k - s - 1); } /*int GetRank(Node *&o, T p, int r) { int s= if (o->s) }*/ void removetree(Node *&x) { if (!x)return; if (x->ch[0] != NULL) removetree(x->ch[0]); if (x->ch[1] != NULL) removetree(x->ch[1]); delete x; x = NULL; } Node *root = NULL; public: int size = 0; int insert(T q){ Insert(root, q); return ++size; } int remove(T q){ if (!find(root, q))return 0; Remove(root, q); return --size; } int Find(T q){ return find(root, q); } int findkth(int k){ return FindKth(root, k); } /*int getrank(T q){ if (!find(root, q))return 0; return GetRank(root, q, 1); }*/ int getrank(T q){ return find(root, q); } ~Treap(){ if (root)removetree(root); } private: void fdebug(Node *a) { if (!a)return; fdebug(a->ch[0]); printf("%d ", a->v); fdebug(a->ch[1]); } public: void debug(){ fdebug(root); } }; int main() { srand(time(0)); Treap<int> t; int n; n = read(); while (n--) { int k, q; k = read(), q = read(); switch (k) { case 1: t.insert(q); break; case 2: t.remove(q); break; case 3: if (t.Find(q)) printf("%d\n", t.size + 1 - t.getrank(q) - lrnk); else { t.insert(q); printf("%d\n", t.size + 1 - t.getrank(q) - lrnk); t.remove(q); } break; case 4: printf("%d\n", t.findkth(t.size + 1 - q)); break; case 5: if (t.Find(q)) printf("%d\n", t.findkth(t.getrank(q) + lrnk + 1)); else { t.insert(q); printf("%d\n", t.findkth(t.getrank(q) + lrnk + 1)); t.remove(q); } break; default: if (t.Find(q)) printf("%d\n", t.findkth(t.getrank(q) - rrnk - 1)); else { t.insert(q); printf("%d\n", t.findkth(t.getrank(q) - rrnk - 1)); t.remove(q); } } // t.debug(); puts(""); }getchar(); return 0; } ```
by cmll02 @ 2020-01-16 22:35:01


|