首页 > 代码库 > bzoj3224: Tyvj 1728 普通平衡树(打个splay暖暖手)

bzoj3224: Tyvj 1728 普通平衡树(打个splay暖暖手)

  (其实今天好热啊?

  题目大意:插入,删除,k小,前驱后继,数的排名。

  splay和treap裸题...过几天补个treap的

splay:

技术分享
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
using namespace std;
const int extar[3]={0,2147483647,-2147483647};
int fa[100010],count[100010],son[100010][3],val[100010],data[100010];
int root,x,y,n,tot;
void read(int &k)
{
    k=0;int f=1;char c=getchar();
    while(c<0||c>9)c==-&&(f=-1),c=getchar();
    while(c<=9&&c>=0)k=k*10+c-0,c=getchar();
    k*=f;
}
void rotate(int x,int w)
{
    int y=fa[x];
    count[y]=count[y]-count[x]+count[son[x][w]];
    count[x]=count[x]+count[y]-count[son[x][w]];
    son[y][3-w]=son[x][w];
    if(son[x][w])fa[son[x][w]]=y;
    fa[x]=fa[y];
    if(fa[y])if(y==son[fa[y]][1])son[fa[y]][1]=x;
    else son[fa[y]][2]=x;
    fa[y]=x;son[x][w]=y;
}
void splay(int x)
{
    int y;
    while(fa[x])
    {
        y=fa[x];
        if(!fa[y])if(son[y][1]==x)rotate(x,2);else rotate(x,1);
        else
        if(son[fa[y]][1]==y)
        {
            if(son[y][1]==x)rotate(y,2),rotate(x,2);
            else rotate(x,1),rotate(x,2);
        }
        else
        {
            if(son[y][2]==x)rotate(y,1),rotate(x,1);
            else rotate(x,2),rotate(x,1);
        }
    }
    root=x;
}
int search(int x,int w)
{
    while(data[x]!=w)
    {
        if(data[x]==w)return x;
        if(data[x]>w)
        {
            if(!son[x][1])break;
            x=son[x][1];
        }
        else
        {
            if(!son[x][2])break;
            x=son[x][2];
        }
    }
    return x;
}
void insert(int w)
{
    if(!tot)
    {
        tot=count[1]=val[1]=root=1;data[1]=w;fa[1]=0;
        return;
    }
    int k=search(root,w),kk=0;
    if(data[k]==w)val[k]++,kk=k;
    else
    {
        data[++tot]=w;count[tot]=val[tot]=1;fa[tot]=k;
        if(w<data[k])son[k][1]=tot;else son[k][2]=tot;
    }
    while(k)count[k]++,k=fa[k];
    if(kk)splay(kk);else splay(tot);
}
int ext(int x,int w)
{
    int k=search(x,extar[w]);
    splay(k);
    return data[k];
}
void del(int w)
{
    int k=search(root,w);
    splay(k);
    if(data[k]==w)
    {
        if(val[k]>1)val[k]--,count[k]--;
        else
        if(!son[k][1])
        {
            root=son[k][2];
            fa[root]=fa[k]=son[k][2]=count[k]=val[k]=data[k]=0;
        }
        else
        {
            fa[son[k][1]]=0;ext(son[k][1],1);
            son[root][2]=son[k][2];
            if(son[k][2])fa[son[k][2]]=root;
            count[root]+=count[son[k][2]];
            fa[k]=son[k][1]=son[k][2]=data[k]=val[k]=count[k]=0;
        }
    }
}
int pred(int w)
{
    int k=search(root,w);
    splay(k);
    if(data[k]<w)return data[k];
    return ext(son[k][1],1);
}
int succ(int x)
{
    int k=search(root,x);
    splay(k);
    if(data[k]>x)return data[k];
    return ext(son[k][2],2);
}
int kth(int cnt,int w)
{
    int i=root;
    while((i!=0)&&(count[son[i][w]]>=cnt||count[son[i][w]]+val[i]<cnt))
    {
        if(count[son[i][w]]+val[i]<cnt)
        {
            cnt-=count[son[i][w]]+val[i];
            i=son[i][3-w];
        }
        else i=son[i][w];
    }
    splay(i);
    return data[i];
}
int findnum(int x,int w)
{
    int k=search(root,x);
    splay(k);
    return count[son[k][w]]+1;
}
int main()
{
    read(n);
    for(int i=1;i<=n;i++)
    {
        read(x);read(y);
        switch(x)
        {
            case 1:insert(y);break;
            case 2:del(y);break;
            case 3:printf("%d\n",findnum(y,1));break;
            case 4:printf("%d\n",kth(y,1));break;
            case 5:printf("%d\n",pred(y));break;
            case 6:printf("%d\n",succ(y));break;
            default:break;
        }
    }
}
View Code

 

bzoj3224: Tyvj 1728 普通平衡树(打个splay暖暖手)