洛谷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\n", getk(root, tmp2));
168         else if(tmp1 == 4)printf("%d\n", getkth(root, tmp2));
169         else if(tmp1 == 5)printf("%d\n", data[getpre(root, tmp2)]);
170         else printf("%d\n", data[getsuc(root, tmp2)]);
171     }
172     return 0;
173 }
大萌神splay

 

posted @ 2017-07-29 15:51  嘒彼小星  阅读(241)  评论(0编辑  收藏  举报