zoukankan      html  css  js  c++  java
  • 洛谷P3369 【模板】普通平衡树(Treap/SBT)

    P3369 【模板】普通平衡树(Treap/SBT)

    题目描述

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

    1. 插入x数

    2. 删除x数(若有多个相同的数,因只删除一个)

    3. 查询x数的排名(若有多个相同的数,因输出最小的排名)

    4. 查询排名为x的数

    5. 求x的前驱(前驱定义为小于x,且最大的数)

    6. 求x的后继(后继定义为大于x,且最小的数)

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例#1:
    10
    1 106465
    4 1
    1 317721
    1 460929
    1 644985
    1 84185
    1 89851
    6 81968
    1 492737
    5 493598
    输出样例#1:
    106465
    84185
    492737

    说明

    时空限制:1000ms,128M

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

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

    来源:Tyvj1728 原名:普通平衡树

    在此鸣谢

    丁队模板,可靠

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <algorithm>
      6  
      7 inline void read(int &x)
      8 {
      9     x = 0;char ch = getchar();char c =ch;
     10     while(ch > '9' || ch < '0')c = ch, ch = getchar();
     11     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
     12     if(c == '-')x = -x;
     13 }
     14  
     15 const int MAXN = 1000000 + 10;
     16  
     17 int fa[MAXN], ch[MAXN][2], size[MAXN], cnt[MAXN],data[MAXN], root, nn, n, tot;
     18  
     19 //左儿子返回0,否则返回1 
     20 int son(int x)
     21 {
     22     return x == ch[fa[x]][1];
     23 }
     24  
     25 void pushup(int rt)
     26 {
     27     int l = ch[rt][0], r = ch[rt][1];
     28     size[rt] = size[l] + size[r] + cnt[rt];
     29 }
     30  
     31  
     32 void rotate(int x)
     33 {
     34     int y = fa[x], z = fa[y], b = son(x), c = son(y), a = ch[x][!b];
     35     if(z) ch[z][c] = x; else root = x; fa[x] = z;
     36     if(a) fa[a] = y; ch[y][b] = a;
     37     ch[x][!b] = y,fa[y] = x;
     38     pushup(y),pushup(x);
     39 }
     40  
     41 void splay(int x, int i)
     42 {
     43     while(fa[x] != i)
     44     {
     45         int y = fa[x], z = fa[y];
     46         if(z == i) rotate(x);
     47         else
     48             if(son(x) == son(y))rotate(y), rotate(x);
     49             else rotate(x), rotate(x);
     50     }
     51 }
     52  
     53 void insert(int &rt, int x)
     54 {
     55     if(rt == 0)
     56     {
     57         rt = ++nn, data[nn] = x, size[nn] = cnt[nn] = 1;
     58         return;
     59     }
     60     if(data[rt] == x)
     61     {
     62         ++cnt[rt], ++size[rt];
     63         return;
     64     }
     65     if(x < data[rt]) insert(ch[rt][0], x), fa[ch[rt][0]] = rt, pushup(rt);
     66     else insert(ch[rt][1], x), fa[ch[rt][1]] = rt, pushup(rt);
     67 }
     68  
     69 int getpre(int rt, int x)
     70 {
     71     int p = rt,ans;
     72     while(p)
     73     {
     74         if(x <= data[p]) p = ch[p][0];
     75         else ans = p, p = ch[p][1];
     76     }
     77     return ans;
     78 }
     79  
     80 int getsuc(int rt, int x)
     81 {
     82     int p = rt,ans;
     83     while(p)
     84     {
     85         if(x >= data[p]) p = ch[p][1];
     86         else ans = p, p = ch[p][0];
     87     }
     88     return ans;
     89 }
     90  
     91 int getmn(int rt)
     92 {
     93     int p = rt, ans = -1;
     94     while(p)
     95     {
     96         ans = p;
     97         p = ch[p][0];
     98     }
     99     return ans;
    100 }
    101  
    102 void del(int rt, int x)
    103 {
    104     if(data[rt] == x)
    105     {
    106         if(cnt[rt] > 1) --cnt[rt], --size[rt];
    107         else
    108         {
    109             splay(rt, 0);
    110             int p = getmn(ch[rt][1]);
    111             if(p != -1)
    112             {
    113                 splay(p, rt);
    114                 root = p,fa[p] = 0,ch[p][0] = ch[rt][0],fa[ch[rt][0]] = p;
    115                 pushup(p);
    116             }
    117             else root = ch[rt][0], fa[ch[rt][0]] = 0;
    118         }
    119         return;
    120     }
    121     if(x < data[rt]) del(ch[rt][0], x);
    122     else del(ch[rt][1], x);
    123     pushup(rt);
    124 }
    125  
    126 int getk(int rt, int k)
    127 {
    128     if(data[rt] == k)
    129     {
    130         splay(rt, 0);
    131         if(ch[rt][0] == 0) return 1;
    132         else return size[ch[rt][0]] + 1;
    133     }
    134     if(k < data[rt])return getk(ch[rt][0], k);
    135     else return getk(ch[rt][1], k);
    136 }
    137  
    138 int gettk(int rt, int k)
    139 {
    140     if(data[rt] == k)
    141     {
    142         splay(rt, 0);
    143         if(ch[rt][0] == 0) return 1;
    144         else return size[ch[rt][0]] + 1;
    145     }
    146     if(k < data[rt]) return gettk(ch[rt][0], k);
    147     else return gettk(ch[rt][0], k);
    148 }
    149  
    150 int getkth(int rt, int k)
    151 {
    152     int l = ch[rt][0];
    153     if(size[l] + 1 <= k && k <= size[l] + cnt[rt]) return data[rt];
    154     if(size[l] + 1 > k)return getkth(ch[rt][0], k);
    155     if(k > size[l] + cnt[rt]) return getkth(ch[rt][1], k - (size[l] + cnt[rt]));
    156 }
    157  
    158 int main()
    159 {
    160     read(n);
    161     for(;n;--n)
    162     {
    163         int tmp1,tmp2;
    164         read(tmp1);read(tmp2);
    165         if(tmp1 == 1)++ tot,insert(root, tmp2);
    166         else if(tmp1 == 2)-- tot, del(root, tmp2);
    167         else if(tmp1 == 3)printf("%d
    ", getk(root, tmp2));
    168         else if(tmp1 == 4)printf("%d
    ", getkth(root, tmp2));
    169         else if(tmp1 == 5)printf("%d
    ", data[getpre(root, tmp2)]);
    170         else printf("%d
    ", data[getsuc(root, tmp2)]);
    171     }
    172     return 0;
    173 }
    大萌神splay
  • 相关阅读:
    众皓网络(T 面试)
    骑芯供应链(T 面试)
    骑芯供应链(W 笔试)
    面试问题_一拉到底
    Java后端学习路线_备战
    docker 容器
    技术展望
    索引 命令
    索引 概念原理
    面试技能更新
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7256156.html
Copyright © 2011-2022 走看看