记录编号 590758 评测结果 AAAAAAAAAA
题目名称 [Tyvj 1728]普通平衡树 最终得分 100
用户昵称 Gravataryrtiop 是否通过 通过
代码语言 C++ 运行时间 0.514 s
提交时间 2024-07-11 11:06:38 内存使用 5.35 MiB
显示代码纯文本
  1. // 大家好啊,今天来点大家想看的东西啊。
  2. #include <bits/stdc++.h>
  3. #define pb emplace_back
  4. #define fir first
  5. #define sec second
  6.  
  7. using i64 = long long;
  8. using u32 = unsigned;
  9. using pii = std::pair<int, int>;
  10. constexpr int maxn = 1e5 + 5;
  11. std::mt19937 rd((unsigned)time(0));
  12.  
  13. struct node {
  14. int ls, rs, val, siz;
  15. u32 key;
  16. node() { ls = rs = val = key = siz = 0; }
  17. node(int ls, int rs, int val, u32 key, int siz) : ls(ls), rs(rs), val(val), key(key), siz(siz) {}
  18. } tr[maxn];
  19.  
  20. int num, rt;
  21.  
  22. int NewNode(int x) {
  23. return tr[++num] = node(0, 0, x, rd(), 1), num;
  24. }
  25.  
  26. void pushup(int x) {
  27. return tr[x].siz = tr[tr[x].ls].siz + tr[tr[x].rs].siz + 1, void();
  28. }
  29.  
  30. void split(int p, int val, int& x, int& y) {
  31. if (!p) return x = y = 0, void();
  32. if (tr[p].val <= val) {
  33. x = p;
  34. split(tr[x].rs, val, tr[x].rs, y);
  35. } else {
  36. y = p;
  37. split(tr[y].ls, val, x, tr[y].ls);
  38. }
  39. return pushup(p);
  40. }
  41.  
  42. int merge(int x, int y) {
  43. if (!x || !y) return x | y;
  44. if (tr[x].key <= tr[y].key) {
  45. tr[x].rs = merge(tr[x].rs, y);
  46. return pushup(x), x;
  47. } else {
  48. tr[y].ls = merge(x, tr[y].ls);
  49. return pushup(y), y;
  50. }
  51. }
  52.  
  53. void insert(int x) {
  54. int a, b, c;
  55. split(rt, x, a, c);
  56. b = NewNode(x);
  57. return rt = merge(a, merge(b, c)), void();
  58. }
  59.  
  60. void remove(int x) {
  61. int a, b, c;
  62. split(rt, x, b, c), split(b, x - 1, a, b);
  63. return rt = merge(a, merge(merge(tr[b].ls, tr[b].rs), c)), void();
  64. }
  65.  
  66. int findrk(int x) {
  67. int a, b, r;
  68. split(rt, x - 1, a, b);
  69. r = tr[a].siz + 1;
  70. return rt = merge(a, b), r;
  71. }
  72.  
  73. void splitrk(int p, int rk, int& x, int& y) {
  74. if (!p) return x = y = 0, void();
  75. if (tr[tr[p].ls].siz + 1 <= rk) {
  76. x = p;
  77. splitrk(tr[p].rs, rk - 1 - tr[tr[p].ls].siz, tr[x].rs, y);
  78. } else {
  79. y = p;
  80. splitrk(tr[p].ls, rk, x, tr[y].ls);
  81. }
  82. return pushup(p);
  83. }
  84.  
  85. int findval(int k) {
  86. int a, b;
  87. splitrk(rt, k, a, b);
  88. int tmp = a;
  89. while (tr[tmp].rs) tmp = tr[tmp].rs;
  90. tmp = tr[tmp].val;
  91. return rt = merge(a, b), tmp;
  92. }
  93.  
  94. int precur(int x) {
  95. return findval(findrk(x) - 1);
  96. }
  97.  
  98. int suffix(int x) {
  99. return findval(findrk(x + 1));
  100. }
  101.  
  102. int main() {
  103. freopen("phs.in", "r", stdin);
  104. freopen("phs.out", "w", stdout);
  105. std::cin.tie(nullptr)->sync_with_stdio(false);
  106. int n;
  107. std::cin >> n;
  108. while (n--) {
  109. int opt, x;
  110. std::cin >> opt >> x;
  111. if (opt == 1) {
  112. insert(x);
  113. } else if (opt == 2) {
  114. remove(x);
  115. } else if (opt == 3) {
  116. std::cout << findrk(x) << '\n';
  117. } else if (opt == 4) {
  118. std::cout << findval(x) << '\n';
  119. } else if (opt == 5) {
  120. std::cout << precur(x) << '\n';
  121. } else {
  122. std::cout << suffix(x) << '\n';
  123. }
  124. }
  125. return 0;
  126. }