zoukankan      html  css  js  c++  java
  • BZOJ 3224: Tyvj 1728 普通平衡树

    3224: Tyvj 1728 普通平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 9275  Solved: 3932
    [Submit][Status][Discuss]

    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.每个数的数据范围:[-1e7,1e7]

    数据如下http://pan.baidu.com/s/1jHMJwO2

    Source

    [Submit][Status][Discuss]

    小生的第二道平衡树板子题。

      1 #include <bits/stdc++.h>
      2 
      3 const int inf = 2e9 + 9;
      4 
      5 class Splay {
      6 public:
      7     Splay(void) {
      8         root = NULL;
      9         for (top = 0; top < siz; ++top)
     10             stk[top] = tree + top;
     11     }
     12     
     13     inline void insert(int val) {
     14         if (find(val) != NULL)
     15             ++root->count, update(root);
     16         else if (root == NULL)
     17             root = newnode(val, NULL);
     18         else 
     19             splay(insert(root, val), NULL);
     20     }
     21     
     22     inline void erase(int val) {
     23         if (find(val) != NULL)
     24             erase(root, 1);
     25     }
     26     
     27     inline int rnk(int val) {
     28         if (find(val) != NULL)
     29             return size(root->son[0]) + 1;
     30         else
     31             return 0;
     32     }
     33     
     34     inline int qry(int kth) {
     35         if (size(root) < kth)
     36             return 0;
     37         for (node *t = root; t; ) {
     38             if (kth > size(t->son[0])) {
     39                 kth -= size(t->son[0]);
     40                 if (kth >= 1 && kth <= t->count)
     41                     return t->value;
     42                 else
     43                     kth -= t->count, t = t->son[1];
     44             }
     45             else
     46                 t = t->son[0];
     47         }
     48     }
     49     
     50     inline int prv(int val) {
     51         int ret = -inf;
     52         for (node *t = root; t; ) {
     53             if (t->value < val)
     54                 if (ret < t->value)
     55                     ret = t->value;
     56             t = t->son[val > t->value];
     57         }
     58         return ret;
     59     }
     60     
     61     inline int nxt(int val) {
     62         int ret = inf;
     63         for (node *t = root; t; ) {
     64             if (t->value > val)
     65                 if (ret > t->value)
     66                     ret = t->value;
     67             t = t->son[val >= t->value];
     68         }
     69         return ret;
     70     }
     71     
     72 private:
     73     struct node {
     74         int size;
     75         int value;
     76         int count;
     77         node *father;
     78         node *son[2];
     79     }*root;
     80     
     81     const static int siz = 1e5 + 5;
     82     
     83     node tree[siz], *stk[siz]; int top;
     84     
     85     inline node *newnode(int v, node *f) {
     86         node *t = stk[--top];
     87         t->size = 1;
     88         t->value = v;
     89         t->count = 1;
     90         t->father = f;
     91         t->son[0] = NULL;
     92         t->son[1] = NULL;
     93         return t;
     94     }
     95     
     96     inline void freenode(node *t) {
     97         stk[top++] = t;
     98     }
     99     
    100     inline int size(node *t) {
    101         return t == NULL ? 0 : t->size;
    102     }
    103     
    104     inline void update(node *t) {
    105         if (t != NULL) {
    106             t->size = t->count;
    107             t->size += size(t->son[0]);
    108             t->size += size(t->son[1]);
    109         }
    110     }
    111     
    112     inline bool son(node *f, node *s) {
    113         if (f == NULL)
    114             return 0;
    115         return f->son[1] == s;
    116     }
    117     
    118     inline void connect(node *f, node *s, bool k) {
    119         if (f != NULL)
    120             f->son[k] = s;
    121         else
    122             root = s;
    123         if (s != NULL)
    124             s->father = f;
    125     }
    126     
    127     inline void rotate(node *t) {
    128         node *f = t->father;
    129         node *g = f->father;
    130         bool a = son(f, t), b = !a;
    131         connect(f, t->son[b], a);
    132         connect(g, t, son(g, f));
    133         connect(t, f, b);
    134         update(f);
    135         update(t);
    136     }
    137     
    138     inline void splay(node *t, node *p) {if (t) {
    139         while (t->father != p) {
    140             node *f = t->father;
    141             node *g = f->father;
    142             if (g == p)
    143                 rotate(t);
    144             else {
    145                 if (son(g, f) ^ son(f, t))
    146                     rotate(t), rotate(t);
    147                 else
    148                     rotate(f), rotate(t);
    149             }
    150         }
    151     }
    152     }
    153     
    154     inline node *find(int val) {
    155         node *ret = root;
    156         while (ret != NULL && ret->value != val)
    157             ret = ret->son[val >= ret->value];
    158         return splay(ret, NULL), ret;
    159     }
    160     
    161     node *insert(node *t, int val) {
    162         node *ret = t->son[val >= t->value];
    163         if (ret == NULL)
    164             ret = t->son[val >= t->value] = newnode(val, t);
    165         else
    166             ret = insert(ret, val);
    167         return update(t), ret;
    168     }
    169     
    170     inline void erase(node *t) {
    171         if (t->son[0] == NULL)
    172             connect(NULL, t->son[1], 0), update(root);
    173         else if (t->son[1] == NULL)
    174             connect(NULL, t->son[0], 0), update(root);
    175         else {
    176             node *p = t->son[0];
    177             while (p->son[1] != NULL)
    178                 p = p->son[1];
    179             splay(p, t);
    180             connect(NULL, p, 0);
    181             connect(p, t->son[1], 1);
    182             update(root);
    183         }
    184         freenode(t);
    185     }
    186     
    187     inline void erase(node *t, int k) {
    188         t->count -= k;
    189         if (t->count <= 0)
    190             erase(t);
    191         else
    192             update(t);
    193     }
    194 }S;
    195 
    196 inline int next(void) {
    197     int ret = 0;
    198     int neg = false;
    199     int bit = getchar();
    200     while (bit <= '0') {
    201         if (bit == '-')
    202             neg ^= true;
    203         bit = getchar();
    204     }
    205     while (bit >= '0') {
    206         ret = ret*10 + bit - '0';
    207         bit = getchar();
    208     }
    209     return neg ? -ret : ret;
    210 }
    211 
    212 signed main(void) {
    213     for (int n = next(); n--; ) {
    214         int opt = next();
    215         int num = next();
    216         if (opt == 1)
    217             S.insert(num);
    218         else if (opt == 2)
    219             S.erase(num);
    220         else if (opt == 3)
    221             printf("%d
    ", S.rnk(num));
    222         else if (opt == 4)
    223             printf("%d
    ", S.qry(num));
    224         else if (opt == 5)
    225             printf("%d
    ", S.prv(num));
    226         else
    227             printf("%d
    ", S.nxt(num));
    228     }
    229 }

    @Author: YouSiki

  • 相关阅读:
    Android架构组件JetPack之DataBinding玩转MVVM开发实战(四)
    echarts统计图踩坑合集
    echarts如何设置背景图的颜色
    小程序获取的用户头像怎么做成圆形
    vue踩坑记-在项目中安装依赖模块npm install报错
    vue踩坑记- Cannot find module 'wrappy'
    编程微刊第七期文章汇总(2018.7)
    从列表中或数组中随机抽取固定数量的元素组成新的数组或列表
    wangEditor
    手把手教你用vue-cli构建一个简单的路由应用
  • 原文地址:https://www.cnblogs.com/yousiki/p/6148122.html
Copyright © 2011-2022 走看看