模板splay树

本来就搞得差不多了,就是insert那个地方一直看不明白,什么root怎么可以这样用,一翻标程,原来它调用的root是son[0][1]这个真的非常迷啊,你什么都不说调用一个root不是很容易让别人造成误解吗,我还纠结了大半节课  好的好的我不应该裱你对不起

后来灵光一现想起来我不是问过我校金牌爷这个问题吗,插入好像有两种方法

1把比插入点大的第一个数转到根,判断大小balabala这个我不是很理解这个具体编法,只是知道原理

我的理解是转到根以后,判断左右插入,然后找前驱找后继连起来

2. 找到叶子节点,直接插入,然后splay到根,这不是好好的吗!多简洁!多明了!多愉快!

3.发现以前好像写错了,这是修改过后的,可以解决重复的问题。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 100010
int fa[maxn],son[maxn][2],siz[maxn],key[maxn],chohe[maxn];
int n,root,tip=0;
void clear()
{
memset(fa,0,sizeof(int));
memset(son,0,sizeof(int));
memset(siz,0,sizeof(int));
memset(key,0,sizeof(int));
memset(chohe,0,sizeof(int));
}
int askflag(int now)
{
if(now==son[fa[now]][0]) return 0;
return 1;
}
void updata(int now)
{siz[now]=1+siz[son[now][0]]+siz[son[now][1]]+chohe[now];}
void rorate(int now)
{
    int flag=askflag(now),f=fa[now];
    if(f!=root) son[fa[fa[now]]][askflag(f)]=now,fa[now]=fa[f];
    else root=now,fa[now]=-1;
    if(son[now][!flag])fa[son[now][!flag]]=f;
    son[f][flag]=son[now][!flag];
    son[now][!flag]=f;
    fa[f]=now;
    updata(f); updata(now);
}
void splay(int now)
{
while(root!=now)
{
if(fa[now]!=root&&fa[fa[now]]!=now)
if(askflag(fa[now])!=askflag(now)) rorate(fa[now]);
else rorate(now);
rorate(now);
}
}
int Kth(int now,int k)
{
if(siz[son[now][0]]+1<=k&&k<=siz[son[now][0]]+1+chohe[now]) return now;
else if(siz[son[now][0]]+1>k&&son[now][0]) return Kth(son[now][0],k);
  else if(son[now][1]&&siz[son[now][0]]+1+chohe[now]<k) 
  return Kth(son[now][1],k-(siz[son[now][0]]+1+chohe[now]));
return -1;
}
int getpos(int now,int val)
{
if(val<key[now]&&siz[son[now][0]]) return getpos(son[now][0],val);
if(val>key[now]&&siz[son[now][1]]) return getpos(son[now][1],val);
return now;
}
void insert(int now)
{
int pos=getpos(root,key[now]);
if(pos==root&&!siz[root])
{
fa[root]=-1;
root=now;
updata(now);
}
else if(key[pos]!=key[now])
{
fa[now]=pos;
if(key[now]<key[pos])son[pos][0]=now;
if(key[now]>key[pos])son[pos][1]=now;
updata(now),updata(pos);
splay(now);
}
else
{
chohe[pos]++;
updata(pos),updata(fa[pos]);
splay(pos);
}
}
void newnode(int x)
{
key[++tip]=x;
if(tip==1) root=tip;
insert(tip);
}
int main()
{
int temp,t;
char c[10],kk;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s%d",c,&temp);
kk=c[0];
if(kk=='I') newnode(temp);
if(kk=='F') 
{
t=Kth(root,temp);
if(t!=-1)printf("%d\n",key[t]),splay(t);
else printf("-1\n");
}
}
}


posted @ 2017-04-09 18:12  OcahIBye  阅读(107)  评论(0编辑  收藏  举报