BZOJ 3224: Tyvj 1728 普通平衡树

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 9286  Solved: 3935
[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

分析:

还是模板题...讲道理这道题我写了3遍才AC...QAQ...

代码:

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdio>
  5 //by NeighThorn
  6 #define inf 1e7+7
  7 using namespace std;
  8 
  9 const int maxn=100000+5;
 10 
 11 int n,opt;
 12 int root,tot,w[maxn],ls[maxn],rs[maxn],fa[maxn],cnt[maxn],siz[maxn];
 13 
 14 inline void zig(int x){
 15     int y=fa[x],tmp=siz[y];
 16     if(rs[x])
 17         ls[y]=rs[x],fa[rs[x]]=y,siz[y]=siz[y]-siz[x]+siz[rs[x]],siz[x]=tmp;
 18     else
 19         ls[y]=0,siz[y]=siz[y]-siz[x],siz[x]=tmp;
 20     fa[x]=fa[y];
 21     if(fa[x]){
 22         if(ls[fa[x]]==y)
 23             ls[fa[x]]=x;
 24         else
 25             rs[fa[x]]=x;
 26     }
 27     fa[y]=x,rs[x]=y;
 28 }
 29 
 30 inline void zag(int x){
 31     int y=fa[x],tmp=siz[y];
 32     if(ls[x])
 33         rs[y]=ls[x],fa[ls[x]]=y,siz[y]=siz[y]-siz[x]+siz[ls[x]],siz[x]=tmp;
 34     else
 35         rs[y]=0,siz[y]=siz[y]-siz[x],siz[x]=tmp;
 36     fa[x]=fa[y];
 37     if(fa[x]){
 38         if(ls[fa[x]]==y)
 39             ls[fa[x]]=x;
 40         else
 41             rs[fa[x]]=x;
 42     }
 43     fa[y]=x,ls[x]=y;
 44 }
 45 
 46 inline void splay(int x,int z){
 47     while(fa[x]!=z){
 48         int y=fa[x];
 49         if(fa[y]==z){
 50             if(ls[y]==x)
 51                 zig(x);
 52             else
 53                 zag(x);
 54         }
 55         else{
 56             if(ls[fa[y]]==y){
 57                 if(ls[y]==x)
 58                     zig(y),zig(x);
 59                 else
 60                     zag(x),zig(x);
 61             }
 62             else{
 63                 if(rs[y]==x)
 64                     zag(y),zag(x);
 65                 else
 66                     zig(x),zag(x);
 67             }
 68         }
 69     }
 70     if(!z)
 71         root=x;
 72 }
 73 
 74 inline void ins(int rt,int x){
 75     if(!rt)
 76         w[++tot]=x,siz[tot]=1,cnt[tot]=1,root=tot;
 77     else if(w[rt]==x)
 78         cnt[rt]++,siz[rt]++,splay(rt,0);
 79     else if(x<w[rt]){
 80         if(!ls[rt])
 81             w[++tot]=x,cnt[tot]=siz[tot]=1,siz[rt]++,fa[tot]=rt,ls[rt]=tot,splay(tot,0);
 82         else
 83             siz[rt]++,ins(ls[rt],x);
 84     }
 85     else{
 86         if(!rs[rt])
 87             w[++tot]=x,cnt[tot]=siz[tot]=1,siz[rt]++,fa[tot]=rt,rs[rt]=tot,splay(tot,0);
 88         else
 89             siz[rt]++,ins(rs[rt],x);
 90     }
 91 }
 92 
 93 inline void del(int rt,int x){
 94     if(w[rt]==x){
 95         splay(rt,0);
 96         if(cnt[rt]>1)
 97             cnt[rt]--,siz[rt]--;
 98         else{
 99             int l=ls[rt],r=rs[rt];
100             if(!l)
101                 ls[rt]=rs[rt]=fa[rt]=siz[rt]=cnt[rt]=0,fa[r]=0,root=r;
102             else{
103                 while(rs[l])
104                     l=rs[l];
105                 splay(l,rt);ls[rt]=rs[rt]=fa[rt]=siz[rt]=cnt[rt]=0;fa[r]=l,rs[l]=r,siz[l]+=siz[r];root=l,fa[l]=0;
106             }
107         }
108     }
109     else if(x<w[rt])
110         del(ls[rt],x);
111     else
112         del(rs[rt],x);
113 }
114 
115 inline int pre(int rt,int x){
116     int res=-inf;
117     while(rt){
118         if(w[rt]<x)
119             res=max(res,w[rt]),rt=rs[rt];
120         else
121             rt=ls[rt];
122     }
123     return res;
124 }
125 
126 inline int suf(int rt,int x){
127     int res=inf;
128     while(rt){
129         if(w[rt]>x)
130             res=min(res,w[rt]),rt=ls[rt];
131         else
132             rt=rs[rt];
133     }
134     return res;
135 }
136 
137 inline int rank(int rt,int x){
138     if(w[rt]==x){
139         splay(rt,0);
140         if(!ls[rt])
141             return 1;
142         else
143             return siz[ls[rt]]+1;
144     }
145     else if(x<w[rt])
146         return rank(ls[rt],x);
147     else
148         return rank(rs[rt],x);
149 }
150 
151 inline int query(int rt,int x){
152     if(!ls[rt]){
153         if(cnt[rt]>=x){
154             splay(rt,0);
155             return w[rt];
156         }
157         else
158             return query(rs[rt],x-cnt[rt]);
159     }
160     else{
161         if(siz[ls[rt]]>=x)
162             return query(ls[rt],x);
163         else if(siz[ls[rt]]+cnt[rt]>=x){
164             splay(rt,0);
165             return w[rt];
166         }
167         else
168             return query(rs[rt],x-siz[ls[rt]]-cnt[rt]);
169     }
170 }
171 
172 signed main(void){
173     memset(ls,0,sizeof(ls));
174     memset(rs,0,sizeof(rs));
175     memset(fa,0,sizeof(fa));
176     memset(cnt,0,sizeof(cnt));
177     memset(siz,0,sizeof(siz));
178     scanf("%d",&n);root=tot=0;
179     for(int i=1,x;i<=n;i++){
180         scanf("%d%d",&opt,&x);
181         if(opt==1)
182             ins(root,x);
183         else if(opt==2)
184             del(root,x);
185         else if(opt==3)
186             printf("%d\n",rank(root,x));
187         else if(opt==4)
188             printf("%d\n",query(root,x));
189         else if(opt==5)
190             printf("%d\n",pre(root,x));
191         else
192             printf("%d\n",suf(root,x));
193     }    
194     return 0;
195 }
View Code

by NeighThorn

posted @ 2016-12-10 10:44  NeighThorn  阅读(136)  评论(0编辑  收藏  举报