• BZOJ 3224 普通平衡树


    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]

    Source

     平衡树裸题,splay大法好。
      1 #include<queue>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 using namespace std;
      5 
      6 #define maxn 100010
      7 const int inf = 1 << 30;
      8 queue <int> team;
      9 struct TREE
     10 {
     11     int ch[maxn][2],fa[maxn],cnt,root;
     12     int key[maxn],size[maxn],t[maxn];
     13     
     14     inline int newnode()
     15     {
     16         if (team.empty()) return ++cnt;
     17         int ret = team.front(); team.pop();
     18         return ret;
     19     }
     20 
     21     inline TREE()
     22     {
     23         root = newnode();
     24         key[root] = -inf; ++t[root];
     25         updata(root);
     26         add(inf);
     27     }
     28 
     29     inline int find(int rank,int have,int now)
     30     {
     31         if (have+size[ch[now][0]]<rank&&have+size[ch[now][0]]+t[now]>=rank) return now;
     32         if (have+size[ch[now][0]]+t[now]<rank) return find(rank,have+size[ch[now][0]]+t[now],ch[now][1]);
     33         else return find(rank,have,ch[now][0]);
     34     }
     35     
     36     inline void updata(int now) { size[now] = size[ch[now][0]] + size[ch[now][1]] + t[now]; }
     37 
     38     inline void rotate(int x)
     39     {
     40         int y = fa[x],z = fa[y],l = ch[y][0] != x,r = l ^ 1;
     41         if (z != 0) ch[z][ch[z][0] != y] = x;
     42         fa[x] = z; fa[y] = x; fa[ch[x][r]] = y;
     43         ch[y][l] = ch[x][r]; ch[x][r] = y;
     44         updata(y); updata(x);
     45     }
     46     
     47     inline void splay(int x,int aim)
     48     {
     49         int p = fa[aim];
     50         while (fa[x] != p)
     51         {
     52             int y = fa[x],z = fa[y];
     53             if (z != p)
     54             {
     55                 if ((ch[z][0] == y)^(ch[y][0] == x)) rotate(x);
     56                 else rotate(y);
     57             }
     58             rotate(x);
     59         }
     60         if (aim == root) root = x;
     61     }
     62 
     63     inline int search(int x)
     64     {
     65         int now = root;
     66         while (now)
     67         {
     68             if (key[now] == x) break;
     69             now = ch[now][x > key[now]];
     70         }
     71         return now;
     72     }
     73 
     74     inline void add(int x)
     75     {
     76         int now = root,pre = 0;
     77         while (now)
     78         {
     79             pre = now;
     80             now = ch[now][x > key[now]];
     81         }
     82         now = newnode();
     83         fa[now] = pre; ch[pre][x > key[pre]] = now;
     84         key[now] = x; ++t[now];
     85         pre = now;
     86         while (now)
     87         {
     88             updata(now);
     89             now = fa[now];
     90         }
     91         splay(pre,root);
     92     }
     93 
     94     inline int qrank(int x)
     95     {
     96         int now = root,ret = 0;
     97         while (key[now] != x)
     98         {
     99             if (x < key[now]) now = ch[now][0];
    100             else ret += size[ch[now][0]] + t[now],now = ch[now][1];
    101         }
    102         return ret + size[ch[now][0]] + 1;
    103     }
    104     
    105     inline void insert(int x)
    106     {
    107         int p = search(x);
    108         if (p)
    109         {
    110             splay(p,root);
    111             ++t[p];
    112             updata(p);
    113         }
    114         else add(x);
    115     }
    116 
    117     inline void del(int x)
    118     {
    119         int now = search(x),k = qrank(x);
    120         int p = find(k-1,0,root),q = find(k + t[now],0,root);
    121         splay(p,root);
    122         splay(q,ch[p][1]);
    123         if (--t[now])
    124         {
    125             updata(now);
    126             updata(q);
    127             updata(p);
    128         }
    129         else
    130         {
    131             ch[q][0] = 0; fa[now] = 0;
    132             updata(q);
    133             updata(p);
    134             team.push(now);
    135         }
    136     }
    137 
    138     inline int ask(int x,int sign)
    139     {
    140         int now = root,ret;
    141         while (now)
    142         {
    143             if (sign)
    144             {
    145                 if (key[now] > x)
    146                     ret = now,now = ch[now][0];
    147                 else now = ch[now][1];
    148             }
    149             else
    150             {
    151                 if (key[now] < x)
    152                     ret = now,now = ch[now][1];
    153                 else now = ch[now][0];
    154             }
    155         }
    156         return key[ret];
    157     }
    158 }tree;
    159 
    160 inline int read()
    161 {
    162     int x=0,f=1;char ch=getchar();
    163     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    164     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    165     return x*f;
    166 }
    167 
    168 int main()
    169 {
    170     freopen("3224.in","r",stdin);
    171     freopen("3224.out","w",stdout);
    172     int T = read();
    173     while (T--)
    174     {
    175         int opt = read();
    176         if (opt == 1) tree.insert(read());
    177         else if (opt == 2) tree.del(read());
    178         else if (opt == 3) printf("%d
    ",tree.qrank(read())-1);
    179         else if (opt == 4) printf("%d
    ",tree.key[tree.find(read()+1,0,tree.root)]);
    180         else if (opt == 5) printf("%d
    ",tree.ask(read(),0));
    181         else printf("%d
    ",tree.ask(read(),1));
    182     }
    183     fclose(stdin); fclose(stdout);
    184     return 0;
    185 }
    View Code
  • 相关阅读:
    MongoDB构架图分享
    如何打印一个对象
    使用thrift进行跨语言调用(php c# java)
    MySQL 数据类型
    海量存储(转)
    Redis文章链接
    关于ActiveMQ的配置
    MySQL TIPS
    如何得到一个随机密码
    MySQL VS Oracle
  • 原文地址:https://www.cnblogs.com/mmlz/p/4294476.html
Copyright © 2020-2023  润新知