题目传送门
裸的伸展树。
解法:
所谓伸展树就是一种平衡树。
自己学吧。
代码实现:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;
int root;
struct node {
int d,n,c,f,son[2];
}tr[110000];int len;
void update(int x) {
int lc=tr[x].son[0],rc=tr[x].son[1];
tr[x].c=tr[lc].c+tr[rc].c+tr[x].n;
}
void add(int d,int f) {
len++;
tr[len].d=d;tr[len].f=f;tr[len].c=tr[len].n=1;
if(d<tr[f].d)
tr[f].son[0]=len;
else
tr[f].son[1]=len;
tr[len].son[0]=tr[len].son[1]=0;
}
void rotate(int x,int w) {
int f=tr[x].f,ff=tr[f].f;
int r,R;
r=tr[x].son[w],R=f;
tr[R].son[1-w]=r;
if(r!=0)
tr[r].f=R;
r=x;R=ff;
if(tr[R].son[0]==f)
tr[R].son[0]=r;
else
tr[R].son[1]=r;
tr[r].f=R;
r=f;R=x;
tr[R].son[w]=r;
tr[r].f=R;
update(f);update(x);
}
int splay(int x,int rt) {
while(tr[x].f!=rt) {
int f=tr[x].f,ff=tr[f].f;
if(ff==rt) {
if(tr[f].son[0]==x)
rotate(x,1);
else
rotate(x,0);
}
else {
if(tr[f].son[0]==x&&tr[ff].son[0]==f) {
rotate(f,1);rotate(x,1);
}
else if(tr[f].son[1]==x&&tr[ff].son[1]==f) {
rotate(f,0);rotate(x,0);
}
else if(tr[f].son[0]==x&&tr[ff].son[1]==f) {
rotate(x,1);rotate(x,0);
}
else {
rotate(x,0);rotate(x,1);
}
}
}
if(rt==0)
root=x;
}
int findip(int d) {
int x=root;
while(tr[x].d!=d) {
if(d<tr[x].d) {
if(tr[x].son[0]==0)
break;
x=tr[x].son[0];
}
else {
if(tr[x].son[1]==0)
break;
x=tr[x].son[1];
}
}
return x;
}
void ins(int d) {
if(len==0) {
add(d,0);root=len;
return ;
}
int x=findip(d);
if(tr[x].d==d) {
tr[x].n++;
update(x);
splay(x,0);
}
else {
add(d,x);
update(x);
splay(len,0);
}
}
void del(int d) {
int x=findip(d);splay(x,0);
if(tr[x].n>1) {
tr[x].n--;update(x);
return ;
}
if(tr[x].son[0]==0&&tr[x].son[1]==0) {
root=len=0;
}
else if(tr[x].son[0]!=0&&tr[x].son[1]==0) {
root=tr[x].son[0];tr[root].f=0;
}
else if(tr[x].son[0]==0&&tr[x].son[1]!=0) {
root=tr[x].son[1];tr[root].f=0;
}
else {
int p=tr[x].son[0];
while(tr[p].son[1]!=0)
p=tr[p].son[1];
splay(p,0);
int r,R;r=tr[x].son[1];R=p;
tr[R].son[1]=r;tr[r].f=R;
root=R;tr[R].f=0;
update(R);
}
}
int findpaiming(int d) {
int x=findip(d);splay(x,0);
return tr[tr[x].son[0]].c+1;
}
int findshuzi(int k) {
int x=root;
while(1) {
int lc=tr[x].son[0],rc=tr[x].son[1];
if(k<=tr[lc].c)
x=lc;
else if(k>tr[lc].c+tr[x].n) {
k-=tr[lc].c+tr[x].n;x=rc;
}
else
break;
}
//splay(x,0);
return tr[x].d;
}
int findqianqu(int d) {
int x=findip(d);splay(x,0);
if(d<=tr[x].d&&tr[x].son[0]!=0) {
x=tr[x].son[0];
while(tr[x].son[1]!=0)
x=tr[x].son[1];
}
if(d<=tr[x].d)
x=0;
return x;
}
int findhouji(int d) {
int x=findip(d);splay(x,0);
if(d>=tr[x].d&&tr[x].son[1]!=0) {
x=tr[x].son[1];
while(tr[x].son[0]!=0)
x=tr[x].son[0];
}
if(d>=tr[x].d)
x=0;
return x;
}
int main() {
int n;scanf("%d",&n);
len=0;root=0;
while(n--) {
int t,x;scanf("%d%d",&t,&x);
if(t==1)
ins(x);
else if(t==2)
del(x);
else if(t==3)
printf("%d\n",findpaiming(x));
else if(t==4)
printf("%d\n",findshuzi(x));
else if(t==5)
printf("%d\n",tr[findqianqu(x)].d);
else
printf("%d\n",tr[findhouji(x)].d);
}
return 0;
}