1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| template <size_t N> class FHQ_Treap { private : int cnt = 0, root = 0, dl = 0, dr = 0, temp = 0; struct treap { int l, r, key, pro, num, size; } tr[N + 5]; void pushup (int k) { tr[k].size = tr[tr[k].l].size + tr[tr[k].r].size + 1; } int newtreap (int x) { tr[++ cnt].key = x; tr[cnt].pro = rand (); tr[cnt].num = tr[cnt].size = 1; return cnt; } void split (int pos, int xx, int& l, int& r) { if (!pos) { l = r = 0; return; } if (tr[pos].key <= xx) { l = pos; split (tr[l].r, xx, tr[l].r, r); } else { r = pos; split (tr[r].l, xx, l, tr[r].l); } pushup (pos); } int merge (int l, int r) { if (!l || !r) { return l | r; } if (tr[l].pro <= tr[r].pro) { tr[l].r = merge (tr[l].r, r); pushup (l); return l; } else { tr[r].l = merge (l, tr[r].l); pushup (r); return r; } } protected : public : void Insert (int xx) { split (root, xx - 1, dl, dr); root = merge (merge (dl, newtreap (xx)), dr); } void Delete (int xx) { split (root, xx - 1, dl, dr); split (dr, xx, temp, dr); temp = merge (tr[temp].l, tr[temp].r); root = merge (dl, merge (temp, dr)); } int Get_Rank (int xx) { split (root, xx - 1, dl, dr); int rank = tr[dl].size + 1; root = merge (dl, dr); return rank; } int Get_Num (int pos, int k = root) { int lsize = tr[tr[pos].l].size + 1; if (lsize == k) { return tr[pos].key; } if (lsize > k) { return Get_Num (tr[pos].l, k); } else { return Get_Num (tr[pos].r, k - lsize); } } int Get_Last (int xx) { split (root, xx - 1, dl, dr); int last = Get_Num (dl, tr[dl].size); root = merge (dl, dr); return last; } int Get_Next (int xx) { split (root, xx, dl, dr); int next = Get_Num (dr, 1); root = merge (dl, dr); return next; } void Delete_All (int k) { int _1, _2, _3, _4; split (root, k - 1, _1, _2); split (_2, k, _3, _4); merge (_1, _4); } } ;
|