求调一只平衡树qaq
查看原帖
求调一只平衡树qaq
246331
cat_lover1楼主2024/9/9 14:30
#include <bits/stdc++.h>
using namespace std;
bool Mbg;
#define int long long
const int N = 1e6 + 10;
int n, opt, x;
struct splay_tree {
  struct node {
    int s[2];
    int& operator[](bool x) { return s[x]; }
    int fa, v, cnt, sz;  // fa,value
    node(int p = 0, int v = 0, bool sz = 0) : fa(p), v(v), cnt(sz), sz(sz) {
      s[0] = s[1] = 0;
    }
  } t[N];
#define p(x) (t[x].fa)
#define S(x, y) (t[t[x][y]])
  int rt, idx;
  void pushup(int x) { t[x].sz = S(x, 0).sz + S(x, 1).sz + t[x].cnt; }
  // reverse x,y(set x's i son to y)
  void rev(int x, bool o, int y) { p(t[x][o] = y) = x; }
#define son(x, y) (t[y][1] == x)  // which son is x in y?
  void rotate(int x) {            // zhong xu bu bian
    int y = p(x), z = p(y);
    bool k = son(x, y);
    rev(z, son(y, z), x);
    rev(y, k, t[x][!k]);
    rev(x, !k, y);
    pushup(y), pushup(x);  // y become son, x become fa
  }
  // shen zhan
  // visit x, rotate it to low k
  // y is root,rt once
  // y is not,linear rt twice
  // zebra
  void splay(int x, int k = 0) {
    while (p(x) != k) {
      int y = p(x), z = p(y);
      if (z ^ k)
        son(x, y) == son(y, z) ? rotate(y) : rotate(x);
      rotate(x);
    }
    if (!k)
      rt = x;
  }
// find num v's pos,rotate it to root
#define dir(r, v) t[r][t[r].v < v]  // which subtree of r is number v in?
  void find(int v) {
    int r = rt;
    for (; dir(r, v) && v != t[r].v;)
      r = dir(r, v);
    splay(r);
  }
  int get(int v, bool k) {  // pre:0,suf:1
    find(v);
    int r = rt;
    if (t[r].v < v && !k)
      return r;
    if (t[r].v > v && k)
      return r;
    for (r = t[r][k]; t[r][!k];)
      r = t[r][!k];
    splay(r);
    return r;
  }
  void del(int v) {  // once
    int pr = get(v, 0), sf = get(v, 1);
    splay(pr, 0), splay(sf, pr);
    int dl = t[sf][0];
    if (t[dl].cnt > 1)
      --t[dl].cnt, splay(dl, 0);
    else
      t[sf][0] = 0, splay(sf, 0);
  }
  int get_val(int k) {
    int u = rt;
    for (int v;;) {
      v = t[u][0];
      if (t[v].sz + t[u].cnt < k)
        k -= t[v].sz + t[u].cnt, u = t[u][1];
      else if (t[v].sz >= k)
        u = v;
      else
        break;
    }
    splay(u);
    assert(rt == u);
    return t[u].v;  // rt=u
  }
  void insert(int v) {
    int x = rt, p = 0;
    while (x && t[x].v != v)
      p = x, x = dir(x, v);
    if (x)
      ++t[x].cnt;
    else {
      t[x = ++idx] = node(p, v, 1);
      t[p][dir(p, v)] = x;
    }
    splay(x);
  }
  int get_rank(int v) {
    // find(v);
    // return S(rt, 0).sz;
    insert(v);
    int res = S(rt, 0).sz;
    del(v);
    return res;
  }
} spt;
bool Med;
main() {
  cerr << 1. * (&Med - &Mbg) / 1048576 << "MB\n";
  cin.tie(0)->sync_with_stdio(0);
  spt.insert(-1e9);
  spt.insert(1e9);
  for (cin >> n; n--;) {
    cin >> opt >> x;
    if (opt == 1)
      spt.insert(x);
    if (opt == 2)
      spt.del(x);
    if (opt == 3)
      cout << spt.get_rank(x) << '\n';
    if (opt == 4)
      cout << spt.get_val(x) << '\n';
    if (opt == 5)
      cout << spt.t[spt.get(x, 0)].v << '\n';
    if (opt == 6)
      cout << spt.t[spt.get(x, 1)].v << '\n';
  }
}
2024/9/9 14:30
加载中...