当前位置: 代码迷 >> 综合 >> bzoj3224 普通平衡树【splay版】
  详细解决方案

bzoj3224 普通平衡树【splay版】

热度:16   发布时间:2024-01-13 12:01:09.0

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每行输出一个数,表示对应答案




二叉平衡树模板题,splay版。

treap版见http://blog.csdn.net/sdfzyhx/article/details/51418974。

替罪羊树版见http://blog.csdn.Net/sdfzyhx/article/details/70212142。



#include<cstdio>
#include<cstring>
struct node
{int f,c[2],x,size,cnt;
}t[100010];
int root,size;
void up(int p)
{t[p].size=t[t[p].c[0]].size+t[t[p].c[1]].size+t[p].cnt;
}
void rot(int p,bool b)
{int x=t[p].f;int y=t[p].c[b];int z=t[y].c[!b];t[x].c[t[x].c[0]!=p]=y;if (y)t[y].f=x;t[y].c[!b]=p;if (p)t[p].f=y;t[p].c[b]=z;if (z)t[z].f=p;up(p);up(y);
}
void splay(int p)
{int x=t[p].f;int y=t[x].f;if (!x) return;if (!y){rot(x,t[x].c[0]!=p);return;}if ((t[x].c[0]==p)^(t[y].c[0]==x))rot(x,t[x].c[0]!=p),rot(y,t[y].c[0]!=p),splay(p);elserot(y,t[y].c[0]!=x),rot(x,t[x].c[0]!=p),splay(p);
}
void ins(int p,int x,int f,bool b)
{if (p==0){p=++size;t[f].c[b]=p;t[p].f=f;t[p].x=x;t[p].size=t[p].cnt=1;splay(p);return;}t[p].size++;if (t[p].x==x){t[p].cnt++;splay(p);return;}ins(t[p].c[x>t[p].x],x,p,x>t[p].x);
}
void del(int p,int x,int f,int b)
{if (t[p].x==x){if (t[p].cnt>1){t[p].size--;t[p].cnt--;return;}if (t[p].c[0]==0&&t[p].c[1]==0){t[f].c[b]=0;return;}if (t[p].c[0]*t[p].c[1]==0){t[f].c[b]=t[p].c[0]+t[p].c[1];if (t[p].c[0])t[t[p].c[0]].f=f;elset[t[p].c[1]].f=f;return;}rot(p,t[t[p].c[1]].size<t[t[p].c[0]].size);t[t[p].f].size--;del(p,x,t[p].f,t[t[p].f].c[0]!=p);return;}t[p].size--;del(t[p].c[x>t[p].x],x,p,x>t[p].x);
}
int ran(int p,int x)
{if (p==0) return 0;if (x<t[p].x) return ran(t[p].c[0],x);if (x==t[p].x){int ans=t[t[p].c[0]].size+1;splay(p);return ans;}return t[t[p].c[0]].size+t[p].cnt+ran(t[p].c[1],x);
}
int que(int p,int x)
{if (p==0) return 0;if (x<=t[t[p].c[0]].size) return que(t[p].c[0],x);if (x<=t[t[p].c[0]].size+t[p].cnt){splay(p);return t[p].x;}return que(t[p].c[1],x-t[t[p].c[0]].size-t[p].cnt);
}
int pre(int p,int x)
{if (p==0) return -1;if (t[p].x<x){int y=pre(t[p].c[1],x);if (y==-1){splay(p);return t[p].x;}return y;}return pre(t[p].c[0],x);
}
int suc(int p,int x)
{if (p==0) return -1;if (t[p].x>x){int y=suc(t[p].c[0],x);if (y==-1){splay(p);return t[p].x;}return y;}return suc(t[p].c[1],x);
}
int main()
{int i,j,k,x,y,n;scanf("%d",&n);for (i=1;i<=n;i++){scanf("%d%d",&x,&y);if (x==1) ins(t[0].c[0],y,0,0);if (x==2) del(t[0].c[0],y,0,0);if (x==3) printf("%d\n",ran(t[0].c[0],y));if (x==4) printf("%d\n",que(t[0].c[0],y));if (x==5) printf("%d\n",pre(t[0].c[0],y));if (x==6) printf("%d\n",suc(t[0].c[0],y));}
}