您的位置:首页 > 其它

平衡树(splay treap)(普通平衡树,郁闷的出纳员)

2017-06-19 19:11 288 查看
splay模板

普通平衡树

#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
4000
)
{
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模板

普通平衡树

#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));
}
}


郁闷的出纳员

#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);
//    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  splay treap 平衡树