先学了splay写的 以后有空再学treap和sbt版
参考: http://blog.csdn.net/clove_unique/article/details/50630280
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define lson i<<1
#define rson i<<1|1
using namespace std;
const int N=1e5+5;
int f[N],ch[N][2],sz[N],cnt[N],key[N];
int tot,root;
inline void Clear(int x)
{
ch[x][0]=ch[x][1]=f[x]=sz[x]=cnt[x]=key[x]=0;
}
inline int get(int x)
{
return ch[f[x]][1]==x;
}
void update(int x)
{
if (x)
{
sz[x]=cnt[x];
if (ch[x][0]) sz[x]+=sz[ch[x][0]];
if (ch[x][1]) sz[x]+=sz[ch[x][1]];
}
}
void Rotate(int x)
{
int fa=f[x],ff=f[fa],kind=get(x);
ch[fa][kind]=ch[x][kind^1];f[ch[x][kind^1]]=fa;
ch[x][kind^1]=fa;f[fa]=x;
f[x]=ff;
if (ff)
ch[ff][ch[ff][1]==fa]=x;
update(fa);
update(x);
}
void splay(int x)
{
for(int fa;(fa=f[x]);Rotate(x))
if (f[fa])
Rotate((get(x)==get(fa)?fa:x));
root=x;
}
void Insert(int x)
{
if (root==0)
{
tot++;
ch[tot][0]=ch[tot][1]=f[tot]=0;
sz[tot]=cnt[tot]=1;
key[tot]=x;
root=tot;
return;
}
int now=root,fa=0;
while(1)
{
if (x==key[now])
{
cnt[now]++;
update(now);
update(fa);
splay(now);
return;
}
fa=now;
now=ch[now][key[now]<x];
if (now==0)
{
tot++;
ch[tot][0]=ch[tot][1]=0;
f[tot]=fa;
sz[tot]=cnt[tot]=1;
ch[fa][key[fa]<x]=tot;
key[tot]=x;
update(fa);
splay(tot);
return;
}
}
}
int Find(int x)
{
int now=root,ans=0;
while(1)
{
if (x<key[now])
now=ch[now][0];
else
{
ans+=(ch[now][0])?sz[ch[now][0]]:0;
if (x==key[now])
{
splay(now);
return ans+1;
}
ans+=cnt[now];
now=ch[now][1];
}
}
}
int Findx(int x)
{
int now=root;
while(1)
{
if (ch[now][0]&&x<=sz[ch[now][0]])
now=ch[now][0];
else
{
int tem=ch[now][0]?sz[ch[now][0]]:0;
tem+=cnt[now];
if (x<=tem) return key[now];
x-=tem;now=ch[now][1];
}
}
}
int pre()
{
int now=ch[root][0];
while(ch[now][1]) now=ch[now][1];
return now;
}
int nextt()
{
int now=ch[root][1];
while(ch[now][0]) now=ch[now][0];
return now;
}
void del(int x)
{
Find(x);
if (cnt[root]>1)
{
cnt[root]--;
return;
}
if (!ch[root][0]&&!ch[root][1])
{
Clear(root);
root=0;
return;
}
if (!ch[root][0])
{
int oldroot=root;
root=ch[root][1];
f[root]=0;
Clear(oldroot);
return;
}
else if (!ch[root][1])
{
int oldroot=root;
root=ch[root][0];
f[root]=0;
Clear(oldroot);
return;
}
int leftbig=pre(),oldroot=root;
splay(leftbig);
f[ch[oldroot][1]]=root;//因为提上来的是最靠近的数,所以不会产生左子树
ch[root][1]=ch[oldroot][1];
Clear(oldroot);
update(root);
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
tot=root=0;
int opt,x;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&opt,&x);
switch(opt)
{
case 1:Insert(x);break;
case 2:del(x);break;
case 3:printf("%d\n",Find(x));break;
case 4:printf("%d\n",Findx(x));break;
case 5:Insert(x);printf("%d\n",key[pre()]);del(x);break;
case 6:Insert(x);printf("%d\n",key[nextt()]);del(x);break;
}
}
}
return 0;
}
HYSBZ 3224 Tyvj 1728 普通平衡树 splay模版
原文:http://www.cnblogs.com/bk-201/p/7383758.html