Balanced tree (splay treap) (ordinary balanced tree, depressed teller)

splay Template

Ordinary balanced tree

#include<cstdio>
#include<iostream>
#define MAXN 100005
int size,tcnt,root;
struct tree{
    int val,sz,cnt;
    int s[2],fa;
};
tree t[MAXN];

bool son(int x)
{
    return t[t[x].fa].s[1] == x;//rc:1,lc:0
}

void rejs(int x)
{
    t[x].sz = t[t[x].s[0]].sz + t[t[x].s[1]].sz + t[x].cnt;
}

void point(int x,int fa,bool z)
{
    if(x)t[x].fa=fa;
    if(fa)t[fa].s[z]=x;
    else root=x;
}

void rotnate(int x)
{
    int y=t[x].fa;
    int z=t[y].fa;
    bool yy=son(y),xx=son(x);
    point(t[x].s[!xx],y,xx);
    point(y,x,!xx);
    point(x,z,yy);
    rejs(y);
    rejs(x);
}

//void rotnate(int x)
//        {
//            int y=t[x].fa,z=t[y].fa;
//            bool xType=son(x),yType=son(y);
//            point(t[x].s[!xType],y,xType);
//            point(y,x,!xType);
//            point(x,z,yType);
//            rejs(y);rejs(x);
//        }


 void splay(int x,int toFa)
        {
            while(t[x].fa!=toFa)
            {
                int xFa=t[x].fa;
                if(t[xFa].fa==toFa) rotnate(x);
                else
                {
                    if(son(xFa)==son(x)) {rotnate(xFa);rotnate(x);}
                    else {rotnate(x);rotnate(x);}
                }
            }
        }

int find(int val)
{
    int x=root;
    while(x)
    {
        if(t[x].val==val)return x;
        if(t[x].val<val)x=t[x].s[1];
        else x=t[x].s[0];
    }
    return 0;
}

int stmax(int x)
{
    int y=0;
    while(x)
    {
        y=x;
        x=t[x].s[1];
    }
    return y;
}

int stmin(int x)
{
    int y=0;
    while(x)
    {
        y=x;
        x=t[x].s[0];
    }
    return y;
}
void insert(int val)
{
    ++size;
    int x=root,y=0;
    while(x)
    {
        y=x;
        if(t[x].val==val)
        {
            ++t[x].cnt;
            splay(x,0);
            return ;
        }
        if(val<t[x].val)x=t[x].s[0];
        else x=t[x].s[1];
    }
    x=++tcnt;
    t[x].val=val;
    t[x].fa=y;
    t[x].cnt=t[x].sz=1;
    point(x,y,val>t[y].val);
    splay(x,0);
}

void erase(int val)
{
    --size;
    int x=find(val);
    if(!x)
    {
        return;
    }
    if(t[x].cnt>1)
    {
        --t[x].cnt;
        splay(x,0);
        return;
    }
    splay(x,0);
    int y=stmax(t[x].s[0]);
    int z=stmin(t[x].s[1]);for(;;);
    if((!y)&&(!z))  size=0,root=0;
    else if(!y)
    {
        splay(z,0);
        t[z].s[0]=0;
        rejs(z); 
    }
    else if(!z)
    {
        splay(y,0);
        t[z].s[1]=0;
        rejs(y);
    }
    else 
    {
        splay(y,0);
        splay(z,y);
        t[z].s[0]=0;
        rejs(z);
        rejs(y);
    }
}

int lower(int val)
{
    int x=root,y=0;
    while(x)
    {
        if(val>t[x].val)y=x,x=t[x].s[1];
        else x=t[x].s[0];
    }
    return t[y].val;
}

int upper(int val)
{
    int x=root,y=0;
    while(x)
    {
        if(val<t[x].val)y=x,x=t[x].s[0];
        else x=t[x].s[1];
    }
    return t[y].val;
}

int rank1(int val)
{
    insert(val);
    int ret=t[t[root].s[0]].sz+1;
    erase(val);
    return ret;
} 

int rank2(int rank)
{
    int x=root;
    while(rank>t[t[x].s[0]].sz+t[x].cnt||rank<=t[t[x].s[0]].sz)
    {
        if(rank<=t[t[x].s[0]].sz)
            x=t[x].s[0];
        else rank-=t[t[x].s[0]].sz+t[x].cnt,x=t[x].s[1];
    }
    return t[x].val;
}

int main()
{
    int n,op,b;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&op,&b);
        if(op==1)insert(b);
        if(op==2)erase(b);
        if(op==3)printf("%d\n",rank1(b));
        if(op==4)printf("%d\n",rank2(b));
        if(op==5)printf("%d\n",lower(b));
        if(op==6)printf("%d\n",upper(b));
    }   
}

treap template

Ordinary balanced tree

#include<cstdio>
#include<iostream>
#include<ctime>
#include<algorithm>

using namespace std;

int root,n,a,b,tmp;
int sz;
struct treap{
    int sz,tot,w,rnd,ch[2];
    int lc,rc;
}t[1000500];

void update(int x)
{
    t[x].sz=t[t[x].ch[0]].sz+t[t[x].ch[1]].sz+t[x].tot;
}

void turn(int &x,int k)
{
    int y=t[x].ch[k^1];
    t[x].ch[k^1]=t[y].ch[k];
    t[y].ch[k]=x;
    update(x);
    update(y);
    x=y;
}

void insert(int &x,int w)
{
    if(!x)
    {
        t[++sz].w=w;
        t[sz].rnd=rand();
        t[sz].tot=t[sz].sz=1;
        x=sz;
    }
    else
    {
        if(t[x].sz++,t[x].w==w)t[x].tot++;

        else if(insert(t[x].ch[tmp=w>t[x].w],w),t[t[x].ch[tmp]].rnd>t[x].rnd)
        {
            turn(x,tmp^1);
        }
    }
}

void del(int &x,int w)
{
    if(!x)return;
    if(t[x].w==w)
    {
        if(t[x].tot>1)t[x].tot--,t[x].sz--;
        else
        {
            if(!(t[x].ch[0]&&t[x].ch[1]))x=t[x].ch[0]|t[x].ch[1];
            else
                turn(x,tmp=t[t[x].ch[0]].rnd>t[t[x].ch[1]].rnd),t[x].sz--,del(t[x].ch[tmp],w);
        }
    }
    else t[x].sz--,del(t[x].ch[w>t[x].w],w);
}

int rank1(int x,int w)
{
    if(t[x].w==w)return t[t[x].ch[0]].sz+1;
    if(t[x].w<w)return t[t[x].ch[0]].sz+t[x].tot+rank1(t[x].ch[1],w);
    else return rank1(t[x].ch[0],w);
}

int kth(int x,int w)
{
    if(!x)return 0;
    if(w<=t[t[x].ch[0]].sz)return kth(t[x].ch[0],w);
    else if(w>t[t[x].ch[0]].sz+t[x].tot)return kth(t[x].ch[1],w-t[t[x].ch[0]].sz-t[x].tot);
    else return t[x].w;
}

int pre(int v)
{
    insert(root,v);
    tmp=kth(root,rank1(root,v)-1);
    del(root,v);
    return tmp;
}

int find(int x,int v)
{
    return t[x].w==v?x:find(t[x].ch[t[x].w<v],v);
}

int sub(int v)
{
    insert(root,v);
    tmp=kth(root,rank1(root,v)+t[find(root,v)].tot);
    del(root,v);
    return tmp;
}

int main()
{

    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&a,&b);
        if(a==1)insert(root,b);
        if(a==2)del(root,b);
        if(a==3)printf("%d\n",rank1(root,b));
        if(a==4)printf("%d\n",kth(root,b));
        if(a==5)printf("%d\n",pre(b));
        if(a==6)printf("%d\n",sub(b));
    }
}

Depressed cashier

#include<cstdio>
#include<iostream>
#include<ctime>
#include<algorithm> 
using namespace std;

int lim,n,m;
char c[2];
struct treap{
    int sz,w,rnd;
    int ch[2];
}t[100005];
int delet,sz,root,tmp;

//void update(int x)
//{
//  t[x].sz=t[t[x].ch[0]].sz+t[t[x].ch[1]].sz+1;
//}

void update(int k)
   {
       t[k].sz=t[t[k].ch[0]].sz+t[t[k].ch[1]].sz+1;
   }

void turn(int &x,int k)
{
    int y=t[x].ch[k^1];
    t[x].ch[k^1]=t[y].ch[k];
    t[y].ch[k]=x;
    update(x);
    update(y);
    x=y;
}

//void rturn(int &k)
//   {
//        int l=t[k].ch[0];
//         t[k].ch[0]=t[l].ch[1]; 
//         t[l].ch[1]=k; 
//         t[l].sz=t[k].sz;
//         update(k);
//         k=l;
//      }
//void lturn(int &k)
//   {
//        int l=t[k].ch[1]; 
//        t[k].ch[1]=t[l].ch[0]; 
//        t[l].ch[0]=k;
//        t[l].sz=t[k].sz;
//        update(k);
//        k=l;
//     }          

void insert(int &x,int w)
{
    if(!x)
    {
        t[++sz].w=w;
        t[sz].rnd=rand();
        t[sz].sz=1; 
        x=sz;
    }
    else
    {

        //if(t[x].sz++,t[x].w==w)t[x].tot++;
        t[x].sz++;
        insert(t[x].ch[tmp=w>t[x].w],w);
        if(t[t[x].ch[tmp]].rnd>t[x].rnd)
        turn(x,tmp^1);
    }
}

//void insert(int &k,int x)
//   {
//        if (k==0)
//              {
//                    sz++;
//                    k=sz;
//                    t[k].w=x;
//                    t[k].rnd=rand();
//                    t[k].sz=1;
//                    return; 
//              }
//         t[k].sz++;
//         if (x<t[k].w)
//              {
//                    insert(t[k].ch[0],x);
//                    if (t[t[k].ch[0]].rnd<t[k].rnd) rturn(k);
//              }
//             else
//               {
//                    insert(t[k].ch[1],x);
//                    if (t[t[k].ch[1]].rnd<t[k].rnd) lturn(k); 
//                  }   
//        }

int del(int &x,int w)
{
    int dt;
    if(!x)return 0;
//  if(t[x].w==w)
//  {
//      if(t[x].tot>1)t[x].tot--;
//      else if(!(t[x].ch[0]&&t[x].ch[1]))x=t[x].ch[0]|t[x].ch[1];
//      else turn(x,tmp=t[t[x].ch[0]].rnd>t[t[x].ch[1]].rnd),t[x].sz--;
//  }
//  else t[x].sz--,del(t[x].ch[w>t[x].w],w); 
    if(t[x].w<w)
    {
        dt=t[t[x].ch[0]].sz+1;
        x=t[x].ch[1];
        return dt+del(x,w);
    }
    else 
    {
        dt=del(t[x].ch[0],w);
        t[x].sz-=dt;
        return dt;
    }
}

//int del(int &k,int x)
//   {
//      int dt;    
//         if (k==0) return 0; 
//         if (t[k].w<x)
//                      {
//                            dt=t[t[k].ch[0]].sz+1;
//                            k=t[k].ch[1];
//                            return dt+del(k,x);
//                      }
//       else
//            {
//                 dt=del(t[k].ch[0],x);
//                 t[k].sz-=dt;
//                 return dt;
//          }               
//   }

//int rank1(int x,int w)
//{
//  if(t[x].w==w)return t[t[x].ch[0]].sz+1;
//  if(t[x].w<w)return rank1(t[x].ch[1],w)+t[t[x].ch[0]].sz+1;
//  else return rank1(t[x].ch[0],w); 
//}

int kth(int x,int w)
{
    if(!x)return 0;
    if(t[t[x].ch[0]].sz+1<w)return kth(t[x].ch[1],w-t[t[x].ch[0]].sz-1);
    else if(t[t[x].ch[0]].sz+1>w)return kth(t[x].ch[0],w);
    else return t[x].w+delet;
}

//int  find (int k,int x) 
//   {
//        if (t[t[k].ch[0]].sz+1==x) return t[k].w+delet;
//            else if (t[t[k].ch[0]].sz+1<x) return find(t[k].ch[1],x-t[t[k].ch[0]].sz-1);
//                    else return find(t[k].ch[0],x);
//} 

int main()
{
    int res;
    scanf("%d%d",&n,&lim);
    for(int i=1;i<=n;i++)
    {
        int x;
        scanf("%s%d",c,&x);
        switch(c[0])
       {
         case 'I': if (x>=lim) insert(root,x-delet);break;
         case 'A': delet+=x;break;
         case 'S':delet-=x; res+=del(root,m-delet); break;
         case 'F':if (x>t[root].sz) printf("-1\n");
                  else
                  printf("%d\n",kth(root,t[root].sz-x+1));    
    }
}
    printf("%d\n",res);
} 

//int main()
//    {
//      int leave;
//        srand(time(0));
//        scanf("%d%d",&n,&m);
//        for (int i=0;i<n;i++)
//           {
//               char ch[2];
//               int x;
//               scanf("%s%d",ch,&x);
//               switch(ch[0])
//                {
//                 case 'I': if (x>=m) insert(root,x-delet);break;
//                 case 'A': delet+=x;break;
//              case 'S':delet-=x; leave+=del(root,m-delet); break;
//              case 'F':if (x>t[root].sz) printf("-1\n");
//                      else
//                          printf("%d\n",find(root,t[root].sz-x+1));         
//            }
//           }
//     printf("%d\n",leave);       
//    }
Published 20 original articles · won praise 1 · views 6324

Guess you like

Origin blog.csdn.net/yichengchangan/article/details/73472446