您的位置:首页 > 其它

bzoj 3224==tyvj 1728普通平衡树 splay

2013-12-05 18:41 597 查看
啊啊啊啊今天各种煞笔啊。。

首先早晨起晚了。。一晚上从11点睡到了7点。。

下午大概三点半开始写这个题。。各种不顺以后发现70分一直超时。。各种方法都不行,后来直接把lyw的子程序都闹过来结果成60 了。。。

最后在6点20 的时候发现了一个恶心的问题!!!!

应该用printf但是我用的是cout!!!!!

当时为了偷懒所以就说先用cout吧,最后就忘了。。。不行不行以后5个数以上都要用cstdio里的东西

这个大概可以作为splay的一般模版了吧。。

下面是代码(话说今天debug的技巧又学了一些)

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define MAX 100086

using namespace std;

int child[MAX][2],father[MAX],cnt[MAX],size[MAX],value[MAX];
int n,i,a1,a2,num=0,root;

void rotate(int p)
{
//cout<<"rotate"<<endl;
int q=father[p],y=father[q],x=(child[q][1]==p);
//if p is q's right person then x==1 else x==0
//if x==1 then rotate_left
//else if x==0 then rotate_right
father[child[q][x]=child[p][x^1]]=q;
father[child[p][x^1]=q]=p;
father[p]=y;
if(y)
child[y][child[y][1]==q]=p;
size[q]=cnt[q]+size[child[q][0]]+size[child[q][1]];
size[p]=cnt[p]+size[child[p][0]]+size[child[p][q]];
//pay more attention = = -> the size of p,q should re_calc
}

void splay(int x,int aim=0)
{
//cout<<"splay"<<endl;
for(int y;(y=father[x])!=aim;rotate(x))
if(father[y]!=aim)
{
if((child[y][0]==x)==(child[father[y]][0]==y))
rotate(y);
else
rotate(x);
}
if(aim==0)
root=x;
/* for(int y;(y=father[x])!=aim;rotate(x))
if(father[y]!=aim)rotate((child[y][0]==x)==(child[father[y]][0]==y)?y:x);
if(aim==0)root=x;*/

size[x]=size[child[x][0]]+cnt[x]+size[child[x][1]];
}

void insert(int x,int k)
{
if(!x)
{
num++;
root=num;
x=num;
value[x]=k;
father[x]=0;
child[x][1]=child[x][0]=0;

cnt[x]=1;
size[x]=1;
return;
}
while(x)
{
size[x]++;
if(k==value[x])
{
cnt[x]++;
return;
}
int &y=child[x][k>value[x]];
if(!y)
{
num++;
y=num;
father[y]=x;
child[y][0]=child[y][1]=0;
cnt[y]=size[y]=1;
value[y]=k;
break;
}
x=y;
}
splay(x);
}

void insert_(int x,int v)
{
if(x==0){root=x=++num;value[x]=v;father[x]=child[x][0]=child[x][1]=0;size[x]=cnt[x]=1;return;}
while(x)
{
size[x]++;
if(v==value[x]){cnt[x]++;return;}
int &y=child[x][v>=value[x]];
if(y==0){y=++num;value[y]=v;father[y]=x;child[y][0]=child[y][1]=0;size[y]=cnt[y]=1;x=y;break;}
x=y;
}
splay(x);
}

int rank_(int x,int k)
{
int ret=0;
while(x)
{
if(k>value[x])
{
ret+=size[child[x][0]]+cnt[x];
x=child[x][1];
}
else
{
if(k==value[x])
return ret+size[child[x][0]]+1;
else
x=child[x][0];
}
}
}

int r_th(int x,int k)
{
while(x)
{
if(k>=size[child[x][0]]+1&&k<=size[child[x][0]]+cnt[x])
return value[x];
if(k>size[child[x][0]]+cnt[x])
{
k-=size[child[x][0]]+cnt[x];
x=child[x][1];
}
else
x=child[x][0];
}
}

int pre(int x,int k)
{
int ans;
while(x)
{
if(value[x]<k)
{
ans=value[x];
x=child[x][1];
}
else
x=child[x][0];
}
return ans;
}

int suc(int x,int k)
{
int ans;
while(x)
{
if(value[x]>k)
{
ans=value[x];
x=child[x][0];
}
else
x=child[x][1];
}
return ans;
}

void debug()
{
cout<<root<<' '<<value[root]<<' '<<value[child[root][0]]<<' '<<value[child[root][1]]<<endl;
cout<<root<<' '<<size[root]<<' '<<size[child[root][0]]<<' '<<size[child[root][1]]<<endl;
cout<<root<<' '<<cnt[root]<<' '<<cnt[child[root][0]]<<' '<<cnt[child[root][1]]<<endl;
}

void read_work_print()
{
cin>>n;
while(n--)
{
//debug();
scanf("%d%d",&a1,&a2);
switch(a1)
{
case 1:
{
insert(root,a2);
break;
}
case 2:
{
delete_(root,a2);
break;
}
case 3:
{
printf("%d\n",rank_(root,a2));
break;
}
case 4:
{
printf("%d\n",r_th(root,a2));
break;
}
case 5:
{
printf("%d\n",pre(root,a2));
break;
}
case 6:
{
printf("%d\n",suc(root,a2));
break;
}
}
}
}

int main()
{
read_work_print();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: