• BZOJ 3224: Tyvj 1728 普通平衡树


    3224: Tyvj 1728 普通平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 9629  Solved: 4091
    [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]

    FHQ Treap

      1 #include <bits/stdc++.h>
      2 
      3 const int N = 500005;
      4 
      5 int ls[N], rs[N], vl[N], tg[N], sz[N];
      6 
      7 inline int node(int v)
      8 {
      9     static int t = 1;
     10     sz[t] = 1;
     11     vl[t] = v;
     12     tg[t] = rand();
     13     return t++;
     14 }
     15 
     16 int merge(int a, int b)
     17 {
     18     if (!a || !b)return a + b;
     19     if (tg[a] > tg[b])
     20     {
     21         rs[a] = merge(rs[a], b);
     22         sz[a] = 1 + sz[ls[a]] + sz[rs[a]];
     23         return a;
     24     }
     25     else
     26     {
     27         ls[b] = merge(a, ls[b]);
     28         sz[b] = 1 + sz[ls[b]] + sz[rs[b]];
     29         return b;
     30     }
     31 }
     32 
     33 void split(int t, int k, int &a, int &b)
     34 {
     35     if (!t)a = b = 0;
     36     else
     37     {
     38         if (vl[t] <= k)
     39             a = t, split(rs[t], k, rs[t], b);
     40         else
     41             b = t, split(ls[t], k, a, ls[t]);
     42         sz[t] = 1 + sz[ls[t]] + sz[rs[t]];
     43     }
     44 }
     45 
     46 int kth(int t, int k)
     47 {
     48     if (k <= sz[ls[t]])
     49         return kth(ls[t], k);
     50     else if (k == sz[ls[t]] + 1)
     51         return t;
     52     else   
     53         return kth(rs[t], k - sz[ls[t]] - 1);
     54 }
     55 
     56 signed main(void)
     57 {
     58     srand(5264);
     59     
     60     int n, r = 0; scanf("%d", &n);
     61 
     62     for (int a, b, x, y, z; n--; )
     63     {
     64         scanf("%d%d", &a, &b);
     65 
     66         if (a == 1)
     67         {
     68             split(r, b, x, y);
     69             r = merge(x, node(b));
     70             r = merge(r, y);
     71         }
     72         else if (a == 2)
     73         {
     74             split(r, b, x, z);
     75             split(x, b - 1, x, y);
     76             y = merge(ls[y], rs[y]);
     77             r = merge(x, y);
     78             r = merge(r, z);
     79         }
     80         else if (a == 3)
     81         {
     82             split(r, b - 1, x, y);
     83             printf("%d
    ", sz[x] + 1);
     84             r = merge(x, y);
     85         }
     86         else if (a == 4)
     87             printf("%d
    ", vl[kth(r, b)]);
     88         else if (a == 5)
     89         {
     90             split(r, b - 1, x, y);
     91             printf("%d
    ", vl[kth(x, sz[x])]);
     92             r = merge(x, y);
     93         }
     94         else
     95         {
     96             split(r, b, x, y);
     97             printf("%d
    ", vl[kth(y, 1)]);
     98             r = merge(x, y);
     99         }
    100     }
    101 }  
     1 #include <bits/stdc++.h>
     2 const int N = 500005;
     3 int ls[N], rs[N], vl[N], tg[N], sz[N], tot = 1;
     4 int node(int v) {
     5     return vl[tot] = v, sz[tot] = 1, tg[tot] = rand(), tot++;
     6 }
     7 int merge(int a, int b) {
     8     if (!a || !b)return a + b;
     9     if (tg[a] > tg[b]) {
    10         rs[a] = merge(rs[a], b);
    11         sz[a] = 1 + sz[ls[a]] + sz[rs[a]];
    12         return a;
    13     }
    14     else {
    15         ls[b] = merge(a, ls[b]);
    16         sz[b] = 1 + sz[ls[b]] + sz[rs[b]];
    17         return b;
    18     }
    19 }
    20 int split(int t, int k, int &a, int &b) {
    21     if (!t)return a = b = 0, 0;
    22     if (vl[t] <= k)
    23         a = t, split(rs[t], k, rs[t], b);
    24     else
    25         b = t, split(ls[t], k, a, ls[t]);
    26     return sz[t] = 1 + sz[ls[t]] + sz[rs[t]];
    27 }
    28 int kth(int t, int k) {
    29     return k <= sz[ls[t]] ? kth(ls[t], k) : ((k -= sz[ls[t]] + 1) ? kth(rs[t], k) : vl[t]);
    30 }
    31 signed main(void) {
    32     int n, r = 0, a, b, x, y, z;
    33     for (scanf("%d", &n); n--; ) {
    34         scanf("%d%d", &a, &b);
    35         if (a == 1)
    36             split(r, b, x, y), r = merge(merge(x, node(b)), y);
    37         else if (a == 2)
    38             split(r, b, x, z), split(x, b - 1, x, y), r = merge(merge(x, merge(ls[y], rs[y])), z);
    39         else if (a == 3)
    40             split(r, b - 1, x, y), printf("%d
    ", sz[x] + 1), r = merge(x, y);
    41         else if (a == 4)
    42             printf("%d
    ", kth(r, b));
    43         else if (a == 5)
    44             split(r, b - 1, x, y), printf("%d
    ", kth(x, sz[x])), r = merge(x, y);
    45         else
    46             split(r, b, x, y), printf("%d
    ", kth(y, 1)), r = merge(x, y);
    47     }
    48 }

    @Author: YouSiki

  • 相关阅读:
    Prototype源码浅析——Object部分(一)
    JS构建页面的DOM节点结构(二)
    Prototype源码浅析——Object部分(二)之类型检测
    createElement与createDocumentFragment的点点区别
    Prototype源码浅析——Function.prototype部分(二)
    CSS3月食
    javascript管中窥豹——形参与实参
    JS获取整个页面的文档
    2012年总结
    Windows下Android环境搭建(最新最方便)
  • 原文地址:https://www.cnblogs.com/yousiki/p/6224736.html
Copyright © 2020-2023  润新知