bzoj3224 普通平衡树 splay模板

时间:2021-12-03 20:12:56

题目传送门

  题目大意:完成一颗splay树。

  思路:模板题,学着还是很有意思的。

  学习splay树:蒟蒻yyb

  该题模板:汪立超

#include<bits/stdc++.h>
#define CLR(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
int root,N=,n,p,q;
int fa[],c[][],size[],sp[];
void rot(int x) {
int y=fa[x],k=(c[y][]==x);
size[y]=size[c[y][k]]+size[c[x][k]]+;
size[x]=size[c[x][!k]]+size[y]+;
c[y][!k]=c[x][k];
fa[c[y][!k]]=y;
fa[x]=fa[y];
if(fa[y])c[fa[y]][c[fa[y]][]==y]=x;
c[x][k]=y;
fa[y]=x;
}
void rots(int x,int g) {//splay
for(int y=fa[x]; y!=g; rot(x),y=fa[x])
if(fa[y]!=g) rot((x==c[y][])==(y==c[fa[y]][])?y:x);
if(g==) root=x;
}
void insert(int x) {//插入
int y=root;
while(c[y][x>sp[y]]) y=c[y][x>sp[y]];
sp[++N]=x;
c[N][]=c[N][]=;
fa[N]=y;
if(y)c[y][x>sp[y]]=N;
rots(N,);
}
void del(int x) {//删除
int y=root;
while(sp[y]!=x) y=c[y][x>sp[y]];
rots(y,);
y=c[root][];
bool b;
if(!y) b=,y=c[root][];
else b=;
while(c[y][b]) y=c[y][b];
rots(y,root);
c[y][b]=c[root][b];
fa[c[root][b]]=y;
fa[y]=;
root=y;
size[y]=size[c[y][!b]]+size[c[y][b]];
}
int rank(int x) {//输出x的rank
int y=root,ans=;
if(x==) {
printf("");
}
while(y)
if(x>sp[y])
ans+=size[c[y][]]+,y=c[y][];
else y=c[y][];
return ans+;
}
int num(int x) {//排名第x的元素
int y=root;
while(x)
if(size[c[y][]]+<x)
x-=size[c[y][]]+,y=c[y][];
else if(size[c[y][]]+==x) return sp[y];
else y=c[y][];
return sp[y];
}
int pre(int x) {//输出前驱
int ans;
for(int y=root; y;)
if(sp[y]<x)
ans=sp[y],y=c[y][];
else y=c[y][];
return ans;
}
int nex(int x) {//输出后驱
int ans;
for(int y=root; y;)
if(sp[y]<=x)
y=c[y][];
else ans=sp[y],y=c[y][];
return ans;
}
int main() {
scanf("%d",&n);
for(int i=; i<=n; i++) {
scanf("%d%d",&p,&q);
if(p==) insert(q);
if(p==) del(q);
if(p==) printf("%d\n",rank(q));
if(p==) printf("%d\n",num(q));
if(p==) printf("%d\n",pre(q));
if(p==) printf("%d\n",nex(q));
}
return ;
}