【BZOJ3224】 【CODEVS4543】 普通平衡树 splay

来源:互联网 发布:java资料 百度云 编辑:程序博客网 时间:2024/05/20 04:27

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 5884 Solved: 2421
[Submit][Status][Discuss]
Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10

1 106465

4 1

1 317721

1 460929

1 644985

1 84185

1 89851

6 81968

1 492737

5 493598

Sample Output

106465

84185

492737

HINT

1.n的数据范围:n<=100000

2.每个数的数据范围:[-1e7,1e7]
Source

平衡树

題意:AS ABOVE;
题解 : ALL KINDS OF STRUCTURES ,AS FOLLOWS
1.0号节点的sz,find的特判;

#include<iostream>#include<stdio.h>#include<queue>#define N 20000005#define inf 1000000000#define ls ch[x][0]#define rs ch[x][1]using namespace std;int ch[N][2];int sz[N];int val[N];int flag=0;int n;int fa[N];int rt;int pp;int an;int tot=0;int num[N];inline void pu(int x){//  if(flag==1)    cout<<" "<<x<<"       "<<ls<<" "<<rs<<endl;    sz[x]=0;    if(ls!=0) sz[x]+=sz[ls];    if(rs!=0) sz[x]+=sz[rs];    sz[x]+=num[x];}inline int is(int x){    return ch[fa[x]][1]==x;}inline void link(int y,int x,int d){    fa[x]=y; ch[y][d]=x;}inline void rotate(int x,int d){    int y=fa[x];    int z=fa[y];    link(y,ch[x][d],!d);    link(z,x,is(y));    link(x,y,d);    pu(y);}void zag(int x){    rotate(x,0);}void zig(int x){    rotate(x,1);}inline void splay(int x,int goal=0){    while(fa[x]!=goal)    {        int y=fa[x];        int z=fa[y];        if(z==goal)         {            rotate(x,!is(x));                       break;        }        if(ch[z][0]==y)        {            if(ch[y][0]==x) zig(y),zig(x);            else zag(x),zig(x);        }        else        {            if(ch[y][1]==x) zag(y),zag(x);            else zig(x),zag(x);        }    }    if(goal==0) rt=x;    pu(x);}inline void newnode(int &x,int father,int v){    x=++tot;    fa[x]=father;    val[x]=v;    num[x]=1;    sz[x]=1;}inline int nex(int x){    if(!ch[x][1]) return 0;    x=ch[x][1];         while(ch[x][0])   x=ch[x][0];    return x;}inline int pre(int x){   int oo;   int tmp=rt;     if(val[tmp]<x) oo=val[tmp];     while(ch[tmp][val[tmp]<x])   {        tmp=ch[tmp][val[tmp]<x];           if(val[tmp]<x) oo=val[tmp];      }   return oo;}inline int hou(int x){   int oo;   int tmp=rt;   if(val[tmp]>x) oo=val[tmp];   while(ch[tmp][val[tmp]<=x])   {        tmp=ch[tmp][val[tmp]<=x];        if(val[tmp]>x) oo=val[tmp];   }   return oo;}inline int find (int x,int k){ //  if(flag)//  {//      cout<<x<<"   "<<sz[ls]<<"            "<<k<<endl;pp++;//      if(pp==3) while(1);//  }    int tmp=sz[ls];    if(ls==0) tmp=0;    if(tmp+1<=k&&tmp+num[x]>=k) return x;    if(tmp+1>k) return find(ls,k);    return find(rs,k-num[x]-tmp);}inline int query_rank(int x){       int oo=0;    int tmp=rt;    while(ch[tmp][val[tmp]<x])      {       //  <<"     "<<val[ch[tmp][val[tmp]<x]]<<endl;        if(val[tmp]==x) break;        if(val[tmp]<x)        {            if(ch[tmp][0])  oo+=sz[ch[tmp][0]];            oo+=num[tmp];        }         tmp=ch[tmp][val[tmp]<x];//  cout<<"   "<<val[tmp]<<"  "<<val[ch[tmp][val[tmp]<x]]<<endl;    }//  cout<<endl;    x=tmp;    an=tmp;    if(ch[tmp][0])  oo+=sz[ch[tmp][0]];    return oo+1; }inline void del(int x){       query_rank(x);    x=an;    splay(x);    if(num[x]>1)    {        num[x]--,pu(x);        return ;    }     else    {        int y=nex(x);        if(y!=0)        {            splay(y,x);            link(y,ch[x][0],0);            link(0,y,is(x));            rt=y;        }        else        {            if(ch[x][0])            {                link(0,ch[x][0],is(x));                rt=ch[x][0];            }            else  rt=ch[0][0]=ch[0][1]=0;        }           pu(y);      }}inline void insert(int k){    int x=rt;    while(ch[x][val[x]<k])    {        if(val[x]==k)        {            num[x]++;            splay(x);            return;        }        x=ch[x][val[x]<k];    }     newnode(ch[x][val[x]<k],x,k);    splay(ch[x][val[x]<k]);}int main(){       int aa,bb;    scanf("%d",&n);         for(int i=1;i<=n;i++)    {        //  cout<<"    "<<rt<<endl;        scanf("%d%d",&aa,&bb);        if(bb==-104772509) flag=1;        if(aa==1)        {            insert(bb);        }        else if(aa==2)        {            del(bb);        }        else if(aa==3)        {            printf("%d\n",query_rank(bb));        }        else if(aa==4)        {//          for(int i=1;i<=10;i++)//          {//              cout<<i<<" "<<val[i]<<" "<<sz[i]<<"     "<<ch[i][0]<<"    "<<ch[i][1]<<endl;//          }cout<<endl<<endl<<endl;while(1);            printf("%d\n",val[find(rt,bb)]);        }        else if(aa==5)        {            printf("%d\n",pre(bb));        }        else if(aa==6)        {            printf("%d\n",hou(bb));        }//      cout<<"          "<<rt<<endl;//      for(int i=1;i<=10;i++)//          {//              cout<<i<<" "<<val[i]<<" "<<sz[i]<<"     "<<ch[i][0]<<"    "<<ch[i][1]<<endl;//          }cout<<endl<<endl<<endl;    }}
1 0