比赛 |
清华集训2017模板练习 |
评测结果 |
AAAAAAAAAA |
题目名称 |
普通平衡树 |
最终得分 |
100 |
用户昵称 |
栋霸霸 |
运行时间 |
0.291 s |
代码语言 |
C++ |
内存使用 |
4.13 MiB |
提交时间 |
2017-07-17 15:08:06 |
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxn=200000;
int key[maxn],lc[maxn],rc[maxn],fa[maxn],siz[maxn];
int tot,root;
int T;
void update(int x)
{
siz[x]=siz[lc[x]]+1+siz[rc[x]];
}
void r_rotate(int x)
{
int y=fa[x];
lc[y]=rc[x];
if(rc[x]!=0) fa[rc[x]]=y;
fa[x]=fa[y];
if(y==lc[fa[y]]) lc[fa[y]]=x;
else rc[fa[y]]=x;
fa[y]=x;
rc[x]=y;
update(x);
update(y);
}
void l_rotate(int x)
{
int y=fa[x];
rc[y]=lc[x];
if(lc[x]!=0) fa[lc[x]]=y;
fa[x]=fa[y];
if(y==lc[fa[y]]) lc[fa[y]]=x;
else rc[fa[y]]=x;
fa[y]=x;
lc[x]=y;
update(x);
update(y);
}
void splay(int x,int s)
{
int p;
while(fa[x]!=s)
{
p=fa[x];
if(fa[p]==s)
{
if(x==lc[p]) r_rotate(x);
else l_rotate(x);
break;
}
if(x==lc[p])
{
if(p==lc[fa[p]]) r_rotate(p),r_rotate(x);
else r_rotate(x),l_rotate(x);
}
else
{
if(p==rc[fa[p]]) l_rotate(p),l_rotate(x);
else l_rotate(x),r_rotate(x);
}
}
if(s==0) root=x;
update(x);
}
int find(int v)
{
int x=root;
while(x!=0)
{
if(v<key[x]) x=lc[x];
else if(v>key[x]) x=rc[x];
else if(v==key[x])
{
splay(x,0);
return x;
}
}
return -1;
}
void New_node(int &x,int fath,int v)
{
x=++tot;
lc[x]=rc[x]=0;
siz[x]=1;
fa[x]=fath;
key[x]=v;
}
void insert(int v)
{
if(root==0)
{
New_node(rc[0],0,v);
root=tot;
return ;
}
int p,x=root;
while(x!=0)
{
p=x;
if(v<=key[x]) siz[x]++,x=lc[x];
else siz[x]++,x=rc[x];
}
if(v<=key[p]) New_node(lc[p],p,v);
else New_node(rc[p],p,v);
splay(tot,0);
}
int getmax(int x)
{
if(rc[x]!=0) return getmax(rc[x]);
return x;
}
int getmin(int x)
{
if(lc[x]!=0) return getmin(lc[x]);
return x;
}
int getpre(int x)
{
splay(x,0);
return getmax(lc[x]);
}
int getne(int x)
{
splay(x,0);
return getmin(rc[x]);
}
void Delete(int v)
{
int x=find(v);
int pp=getmax(lc[x]);
int nn=getmin(rc[x]);
if(lc[x]==0||rc[x]==0)
{
if(lc[x]==0&&rc[x]==0)
{
root=0;
rc[0]=0;
return ;
}
if(lc[x]==0)
{
rc[0]=rc[x];
fa[rc[x]]=0;
root=rc[x];
rc[x]=0;
siz[x]=1;
return ;
}
else
{
rc[0]=lc[x];
fa[lc[x]]=0;
root=lc[x];
lc[x]=0;
siz[x]=1;
return ;
}
}
splay(pp,0);
splay(nn,root);
fa[lc[nn]]=0;
siz[lc[nn]]=1;
lc[nn]=0;
update(nn);
update(pp);
}
int rank(int rt,int v)
{
if(rt==0) return 1;
if(v<=key[rt]) return rank(lc[rt],v);
else return siz[lc[rt]]+1+rank(rc[rt],v);
}
int findkth(int x,int k)
{
if(siz[lc[x]]+1==k) return key[x];
if(siz[lc[x]]+1>k) return findkth(lc[x],k);
return findkth(rc[x],k-siz[lc[x]]-1);
}
int pred(int rt,int v)
{
if(rt==0) return v;
if(v<=key[rt]) return pred(lc[rt],v);
else
{
int ans=pred(rc[rt],v);
if(ans==v) return key[rt];
return ans;
}
}
int succ(int rt,int v)
{
if(rt==0) return v;
if(v>=key[rt]) return succ(rc[rt],v);
else
{
int ans=succ(lc[rt],v);
if(ans==v) return key[rt];
return ans;
}
}
int main()
{
freopen("phs.in","r",stdin);
freopen("phs.out","w",stdout);
scanf("%d",&T);
while (T--)
{
int kin,num;
scanf("%d%d",&kin,&num);
if(kin==1)
insert(num);
else if(kin==2)
Delete(num);
else if(kin==3)
printf("%d\n",rank(root,num));
else if (kin==4)
printf("%d\n",findkth(root,num));
else if (kin==5)
printf("%d\n",pred(root,num));
else if (kin==6)
printf("%d\n",succ(root,num));
}
return 0;
}