zoukankan      html  css  js  c++  java
  • [代码] bzoj 3224 普通平衡树(无旋treap)

    - 传送门 -

     http://www.lydsy.com/JudgeOnline/problem.php?id=3224
     

    3224: Tyvj 1728 普通平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 17311  Solved: 7553

    Description

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
    1. 插入x数
    2. 删除x数(若有多个相同的数,因只删除一个)
    3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
    4. 查询排名为x的数
    5. 求x的前驱(前驱定义为小于x,且最大的数)
    6. 求x的后继(后继定义为大于x,且最小的数)

    Input

    第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

    Output

    对于操作3,4,5,6每行输出一个数,表示对应答案

    Sample Input

    10
    1 106465
    4 1
    1 317721
    1 460929
    1 644985
    1 84185
    1 89851
    6 81968
    1 492737
    5 493598

    Sample Output

    106465
    84185
    492737

    HINT

    1.n的数据范围:n<=100000

    2.每个数的数据范围:[-2e9,2e9]
     

    - 代码 -

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <ctime>
    #include <cstdlib>
    #define pii pair<int, int>
    #define mp make_pair
    using namespace std;
    
    template <typename ty> void read(ty &x) {
      x = 0; int f = 1; char ch = getchar();
      while (ch > '9' || ch < '0') { if (ch == '-') f = -1; ch = getchar(); }
      while (ch >= '0' && ch <= '9') { x = x*10 + ch - '0'; ch = getchar(); }
      x *= f;
    }
    template <typename ty> ty Max(ty a, ty b) { return a > b ? a : b; }
    template <typename ty> ty Min(ty a, ty b) { return a < b ? a : b; }
    template <typename ty> int Chkmin(ty a, ty b) { return a > b ? a = b, 1 : 0; }
    template <typename ty> int Chkmax(ty a, ty b) { return a < b ? a = b, 1 : 0; }
    
    typedef long long LL;
    typedef double db;
    
    const int inf = 0x7fffffff;
    const int N = 1e5 + 16;
    
    int V[N], C[N][2], SZ[N], RD[N];
    int n, sz, tot, root;
    
    void pushup(int rt) { SZ[rt] = SZ[C[rt][0]] + SZ[C[rt][1]] + 1; }
    
    int build(int val) {
    
      sz++;
      V[sz] = val;
      RD[sz] = rand();
      SZ[sz] = 1;
      return sz;
    
    }
    
    pii split(int rt, int k) {
    
      if (!rt) return mp(0, 0);
      pii tmp;
      if (SZ[C[rt][0]] >= k) {
        tmp = split(C[rt][0], k); C[rt][0] = tmp.second;
        pushup(rt); tmp.second = rt;
      }
      else {
        tmp = split(C[rt][1], k - SZ[C[rt][0]] - 1); C[rt][1] = tmp.first;
        pushup(rt); tmp.first = rt;
      }
      return tmp;
    
    }
    
    int merge(int ra, int rb) {
    
      if (!ra) return rb;
      if (!rb) return ra;
      if (RD[ra] < RD[rb]) {
        C[ra][1] = merge(C[ra][1], rb);
        pushup(ra); return ra;
      }
      else {
        C[rb][0] = merge(ra, C[rb][0]);
        pushup(rb); return rb;
      }
    
    }
    
    int getkth(int rt, int val) {
    
      if (!rt) return 0;
      if (V[rt] >= val) return getkth(C[rt][0], val);
      return SZ[C[rt][0]] + 1 + getkth(C[rt][1], val);
    
    }
    
    int findkth(int rt, int k) {
    
      pii a = split(root, k - 1);
      pii b = split(a.second, 1);
      int ans = b.first;
      root = merge(merge(a.first, ans), b.second);
      return ans;
    
    }
    
    void work1(int v) {
    
      int tmp = getkth(root, v);
      pii a = split(root, tmp);
      root = merge(merge(a.first, build(v)), a.second);
    
    }
    
    void work2(int v) {
    
      int tmp = getkth(root, v);
      int t = findkth(root, tmp + 1);
      if (!t || V[t] != v) return;
    
      pii a = split(root, tmp);
      pii b = split(a.second, 1);
      root = merge(a.first, b.second);
    
    }
    
    void work3(int v) { printf("%d
    ", getkth(root, v) + 1); }
    
    void work4(int v) { printf("%d
    ", V[findkth(root, v)]); }
    
    void work5(int v) { printf("%d
    ", V[findkth(root, getkth(root, v))]); }
    
    void work6(int v) { printf("%d
    ", V[findkth(root, getkth(root, v + 1) + 1)]); }
    
    int main () {
    
      read(n);
      while (n --) {
        int opt, v;
        read(opt); read(v);
        switch(opt) {
          case 1: { work1(v); break; }
          case 2: { work2(v); break; }
          case 3: { work3(v); break; }
          case 4: { work4(v); break; }
          case 5: { work5(v); break; }
          case 6: { work6(v); break; }
        }
      }
    
      return 0;
    
    }
    
  • 相关阅读:
    Linux Shell处理文本最常用的工具大盘点
    Linux GCC常用命令
    IT运维流程 — ITIL
    linux软件安装与卸载
    ifconfig无输出的解决办法
    du 命令秘籍
    linux主机名的修改
    输错密码?这个 sudo 会“嘲讽”你
    VS开发环境美化
    oracle +plsql装完省略号不能点
  • 原文地址:https://www.cnblogs.com/Anding-16/p/8010747.html
Copyright © 2011-2022 走看看