萌新求助 Treap
查看原帖
萌新求助 Treap
176843
LiveZoom楼主2022/1/19 18:02

代码:

#include <bits/stdc++.h>

using namespace std;

const int kInf = 0x3f3f3f3f;
const int kMaxN = 1e5 + 5;

int n, opt, x;
int rt, ans;

class Treap {
  public:
    int newNode (int x) {
      val[++tot] = x;
      sz[tot] = cnt[tot] = 1;
      dat[tot] = rand();
      return tot;
    }
    void pushup (int k) {
      sz[k] = sz[lc[k]] + sz[rc[k]] + cnt[k];
    }
    void build () {
      newNode(-kInf), newNode(kInf);
      rt = 1, rc[1] = 2;
      pushup(rt);
    }
    void zig (int& k) { // left rotate
      int p = lc[k];
      lc[k] = rc[p], rc[p] = k, k = p;
      pushup(rc[k]), pushup(k);
    }
    void zag (int& k) { // right rotate
      int p = rc[k];
      rc[k] = lc[p], lc[p] = k, k = p;
      pushup(lc[k]), pushup(k);
    }
    void ins (int& k, int x) {
      if (!k) {
        k = newNode(x);
        return ;
      }
      if (x == val[k]) {
        ++cnt[k];
      }
      else if (x < val[k]) {
        ins(lc[k], x);
        if (dat[k] < dat[lc[k]]) {
          zig(k);
        }
      }
      else {
        ins(rc[k], x);
        if (dat[k] < dat[rc[k]]) {
          zag(k);
        }
      }
      pushup(k);
    }
    void del (int& k, int x) {
      if (!k) {
        return ;
      }
      if (val[k] == x) {
        if (cnt[k] > 1) {
          --cnt[k], --sz[k];
          return ;
        }
        if (!lc[k] || !rc[k]) {
          k = lc[k] + rc[k];
          return ;
        }
        else if (lc[k] || rc[k]) {
          if (dat[lc[k]] < dat[rc[k]]) {
            zag(k);
            del(rc[k], x);
          }
          else {
            zig(k);
            del(lc[k], x);
          }
          return ;
        }
        else {
          k = 0;
        }
      }
      else if (val[k] > x) {
        del(lc[k], x);
        --sz[k];
        return ;
      }
      else {
        del(rc[k], x);
        --sz[k];
      }
      return ;
    }
    int queryRank (int k, int x) {
      if (!k) {
        return 0;
      }
      if (val[k] == x) {
        return sz[lc[k]] + 1;
      }
      else if (val[k] > x) {
        return queryRank(lc[k], x);
      }
      else {
        return sz[lc[k]] + cnt[k] + queryRank(rc[k], x);
      }
    }
    int queryKth (int k, int x) {
      if (!k) {
        return kInf;
      }
      if (sz[lc[k]] >= x) {
        return queryKth(lc[k], x);
      }
      else if (x <= sz[lc[k]] + cnt[k]) {
        return val[k];
      }
      else {
        return queryKth(rc[k], x - sz[lc[k]] - cnt[k]);
      }
    }
    void queryPre (int k, int x) {
      if (!k) {
        return ;
      }
      if (val[k] < x) {
        ans = val[k];
        return queryPre(rc[k], x);
      }
      else {
        return queryPre(lc[k], x);
      }
    }
    void querySub (int k, int x) {
      if (!k) {
        return ;
      }
      if (val[k] > x) {
        ans = val[k];
        return querySub(lc[k], x);
      }
      else {
        return querySub(rc[k], x);
      }
    }
  private:
    int tot, lc[kMaxN], rc[kMaxN], val[kMaxN], dat[kMaxN], sz[kMaxN], cnt[kMaxN];
} T ;

int main() {
  freopen("P3369.in", "r", stdin);
  srand(2333);
  T.build();
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d%d", &opt, &x);
    if (opt == 1) {
      T.ins(rt, x);
    }
    else if (opt == 2) {
      T.del(rt, x);
    }
    else if (opt == 3) {
      printf("%d\n", T.queryRank(rt, x) - 1);
    }
    else if (opt == 4) {
      printf("%d\n", T.queryKth(rt, x + 1));
    }
    else if (opt == 5) {
      ans = 0;
      T.queryPre(rt, x);
      printf("%d\n", ans);
    }
    else {
      ans = 0;
      T.querySub(rt, x);
      printf("%d\n", ans);
    }
  }
  return 0;
}

第 3 个点本地测能过,但交上去就 WA 了,WA 的点是求排名为 xx 的。

2022/1/19 18:02
加载中...