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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| #include<bits/stdc++.h> using namespace std; const int MAXn = 1e5; const int INF = 0x3f3f3f3f;
template <typename T> inline void read(T &a) { char c;for (c = getchar(); (c < '0' || c > '9') && c != '-'; c = getchar());bool f = c == '-';T x = f ? 0 : (c ^ '0');for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) {x = x * 10 + (c ^ '0');}a = f ? -x : x; } template <typename T, typename ...Argv> inline void read(T &a, Argv &...argv) { read(a), read(argv...); }
int cntnd, son[MAXn + 10][2], siz[MAXn + 10], num[MAXn + 10], val[MAXn + 10], rd[MAXn + 10]; inline void pushup(int cur) { siz[cur] = siz[son[cur][0]] + siz[son[cur][1]] + num[cur]; } inline void rotate(int &cur, int side) { int y = son[cur][side ^ 1]; int z = son[y][side]; son[cur][side ^ 1] = z; son[y][side] = cur; pushup(cur); pushup(y); cur = y; } inline void Insert(int &cur, int v) { if (!cur) { cur = ++cntnd; siz[cur] = num[cur] = 1; val[cur] = v; rd[cur] = rand(); } else if (v == val[cur]) { ++siz[cur]; ++num[cur]; } else { int side = (v > val[cur]); Insert(son[cur][side], v); if (rd[son[cur][side]] > rd[cur]) { rotate(cur, side ^ 1); } else { ++siz[cur]; } } } inline void Delete(int &cur, int v) { if (!cur) { ; } else if (v == val[cur]) { if (num[cur] > 2) { --num[cur]; } else if (!son[cur][0] && !son[cur][1]) { --num[cur]; --siz[cur]; if (!siz[cur]) cur = 0; return; } else if (son[cur][0] && !son[cur][1]) { rotate(cur, 1); Delete(son[cur][1], v); } else if (!son[cur][0] && son[cur][1]) { rotate(cur, 0); Delete(son[cur][0], v); } else { int side = (rd[son[cur][0]] < rd[son[cur][1]]); rotate(cur, side ^ 1); Delete(son[cur][side ^ 1], v); } --siz[cur]; } else { int side = (v > val[cur]); Delete(son[cur][side], v); pushup(cur); } } inline int valtorank(int cur, int v) { if (!cur) return 0; if (v < val[cur]) { return valtorank(son[cur][0], v); } else if (v > val[cur]) { return siz[son[cur][0]] + num[cur] + valtorank(son[cur][1], v); } else { return siz[son[cur][0]]; } } inline int ValtoRank(int cur, int v) { return valtorank(cur, v) + 1; } inline int RanktoVal(int cur, int rank) { if (!cur) return -INF; if (rank >= siz[son[cur][0]] + 1 && rank <= siz[son[cur][0]] + num[cur]) { return val[cur]; } else if (rank <= siz[son[cur][0]]) { return RanktoVal(son[cur][0], rank); } else { return RanktoVal(son[cur][1], rank - (siz[son[cur][0]] + num[cur])); } } inline int Pre(int cur, int v) { if (!cur) return -INF; if (val[cur] >= v) { return Pre(son[cur][0], v); } else { return max(val[cur], Pre(son[cur][1], v)); } } inline int Nex(int cur, int v) { if (!cur) return INF; if (val[cur] <= v) { return Nex(son[cur][1], v); } else { return min(val[cur], Nex(son[cur][0], v)); } }
int n, root; signed main() { read(n); for (int i = 1, opt, x; i <= n; ++i) { read(opt, x); if (opt == 1) Insert(root, x); else if (opt == 2) Delete(root, x); else if (opt == 3) printf("%d\n", ValtoRank(root, x)); else if (opt == 4) printf("%d\n", RanktoVal(root, x)); else if (opt == 5) printf("%d\n", Pre(root, x)); else if (opt == 6) printf("%d\n", Nex(root, x)); } return 0; }
|