3224: Tyvj 1728 普通平衡树(新板子)

Posted HWIM

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了3224: Tyvj 1728 普通平衡树(新板子)相关的知识,希望对你有一定的参考价值。

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 17048  Solved: 7429
[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.每个数的数据范围:[-2e9,2e9]

 

 

code

更新了下板子

 

  1 #include<cstdio>
  2  
  3 const int N = 100010;
  4 int fa[N],ch[N][2],siz[N],cnt[N],data[N];
  5 int tn,Root;
  6 
  7 inline char nc() {
  8     static char buf[100000],*p1 = buf,*p2 = buf;
  9     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF :*p1++;
 10 }
 11 inline int read() {
 12     int x = 0,f = 1;char ch=nc();
 13     for (; ch<0||ch>9; ch = nc()) 
 14         if (ch == -) f = -1;
 15     for (; ch>=0&&ch<=9; ch = nc()) 
 16         x = x*10+ch-0;
 17     return x * f;
 18 }
 19 inline int son(int x) {
 20     return x == ch[fa[x]][1]; // - 
 21 }
 22 inline void pushup(int x) {
 23     siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + cnt[x];
 24 }
 25 inline void rotate(int x) {
 26     int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b];
 27     if (z) ch[z][c] = x;else Root = x;fa[x] = z; // 调整x的位置
 28     ch[x][!b] = y;fa[y] = x; // 调整y的位置
 29     ch[y][b] = a;if (a) fa[a] = y; // 给y另一个子节点
 30     pushup(y);pushup(x);
 31 }
 32 inline void splay(int x,int rt) {
 33     while (fa[x] != rt) {
 34         int y = fa[x],z = fa[y];
 35         if (z==rt) rotate(x);
 36         else {
 37             if (son(x)==son(y)) rotate(y),rotate(x);
 38             else rotate(x),rotate(x);
 39         }
 40     }
 41 }
 42 inline int getpre(int x) { //得到第一个比x小的数 
 43     int p = Root,ans;
 44     while (p) {
 45         if (x <= data[p]) p = ch[p][0];
 46         else ans = p,p = ch[p][1];
 47     }
 48     return ans;
 49 }
 50 inline int getsuc(int x) { // 得到第一个比x大的数
 51     int p = Root,ans;
 52     while (p) {
 53         if (x >= data[p]) p = ch[p][1];
 54         else ans = p,p = ch[p][0];
 55     }
 56     return ans;
 57 }
 58 inline int getk(int k) { // 得到k的排名
 59     int p = Root,ans = 0;
 60     while (true) {
 61         if (k < data[p]) p = ch[p][0];
 62         else {
 63             ans += (ch[p][0] ? siz[ch[p][0]] : 0);
 64             if (k==data[p]) {
 65                 splay(p,0);return ans+1;
 66             }
 67             ans += cnt[p];
 68             p = ch[p][1];
 69         }
 70     }
 71 }
 72 inline int getkth(int k) { // 得到第k个数
 73     int p = Root;
 74     while (true) {
 75         if (ch[p][0] && k <= siz[ch[p][0]]) p = ch[p][0];
 76         else {
 77             int tmp = (ch[p][0] ? siz[ch[p][0]] : 0) + cnt[p];
 78             if (k <= tmp) return data[p];
 79             k -= tmp; p = ch[p][1];
 80         }
 81     }
 82 }
 83 inline void Insert(int x) { // 插入
 84     if (Root==0) {
 85         ++tn; Root = tn; 
 86         ch[tn][1] = ch[tn][0] = fa[tn] = 0;
 87         siz[tn] = cnt[tn] = 1;data[tn] = x;
 88         return;
 89     }
 90     int p = Root,pa = 0;
 91     while (true) {
 92         if (x==data[p]) {
 93             cnt[p]++;pushup(p);pushup(pa);splay(p,0);break;
 94         }
 95         pa = p;
 96         p = ch[p][x > data[p]];
 97         if (p==0) {
 98             tn++;
 99             ch[tn][1] = ch[tn][0] = 0;siz[tn] = cnt[tn] = 1;
100             fa[tn] = pa;ch[pa][x > data[pa]] = tn;data[tn] = x; //-
101             pushup(pa),splay(tn,0);break;
102         }
103     }
104 }
105 inline void Clear(int x) {
106     ch[x][0] = ch[x][1] = fa[x] = siz[x] = cnt[x] = data[x] = 0;
107 }
108 inline void Delete(int x) { // 删除
109     getk(x);
110     if (cnt[Root] > 1) {cnt[Root]--;pushup(Root);return;}
111     if (!ch[Root][0] && !ch[Root][1]) {Clear(Root);Root = 0;return;}
112     if (!ch[Root][0]) {
113         int tmp = Root;Root = ch[Root][1];fa[Root] = 0;Clear(tmp);return;
114     }
115     else if (!ch[Root][1]) {
116         int tmp = Root;Root = ch[Root][0];fa[Root] = 0;Clear(tmp);return;
117     }
118     int tmp = Root,pre = ch[Root][0];//可以是getpre(data[Root]);等价于下面的while 
119     while (ch[pre][1]) pre = ch[pre][1];
120     splay(pre,0);
121     ch[Root][1] = ch[tmp][1];
122     fa[ch[tmp][1]] = Root;
123     Clear(tmp);
124     pushup(Root);
125 }
126 int main() {
127     int n = read();
128     while (n--){
129         int opt = read(),x = read();
130         if (opt==1) Insert(x);
131         else if (opt==2) Delete(x);
132         else if (opt==3) printf("%d\n",getk(x));
133         else if (opt==4) printf("%d\n",getkth(x));
134         else if (opt==5) printf("%d\n",data[getpre(x)]);
135         else printf("%d\n",data[getsuc(x)]);
136     }
137     return 0;
138 }

 

 

 

 

 

以上是关于3224: Tyvj 1728 普通平衡树(新板子)的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 3224 Tyvj 1728 普通平衡树 | Splay 板子

3224: Tyvj 1728 普通平衡树

bzoj3224: Tyvj 1728 普通平衡树

bzoj 3224: Tyvj 1728 普通平衡树.

bzoj 3224 Tyvj 1728 普通平衡树

bzoj3224: Tyvj 1728 普通平衡树 treap