POJ - 3481 splay板子

Double Queue

默写splay板子

很多细节问题。。。

#include<cstdio>
#include<iostream>
using namespace std;
#define maxn 1000005
int root;
int tot=0;
int ch[maxn][2],par[maxn];
int cnt[maxn],size[maxn];
int val[maxn],dat[maxn];
void pushup(int x)
{
    size[x]=cnt[x]+size[ch[x][0]]+size[ch[x][1]];
}///size信息
bool which(int x)
{
    return ch[par[x]][1]==x;
}
void rotate(int x)
{
    int y=par[x],z=par[y];///?
    int w=which(x);
    int t=ch[x][w^1];
    par[t]=y;
    ch[y][w]=t;
    //par[t]=y;
    par[x]=z;
    ch[z][which(y)]=x;
    //par[x]=z;
    par[y]=x;
    ch[x][w^1]=y;
    //par[y]=x;
    pushup(y);
    pushup(x);
}
void splay(int x,int goal=0)
{
    if(x==0)return;
    int y,z;
    while(par[x]!=goal)///为什么不是x
    {
        // cout<<"PAR"<<par[x]<<endl;
        y=par[x],z=par[y];
        //cout<<x<<y<<z<<"YZ"<<endl;
        if(z!=goal) ///???
        {
            if(which(x)==which(y))
            {
                rotate(y);
            }
            else rotate(x);
        }
        rotate(x);
        // x=par[x];
        // y=par[y];
    }

    if(!goal)root=x;
}
void find(int x)
{
    int cur=root;
    while(ch[cur][x>val[cur]]&&x!=val[cur])
    {
        cur=ch[cur][x>val[cur]];
    }///为什么不维护父节点了?
    splay(cur);
}
int pre(int x)
{
    find(x);
    int cur=ch[root][0];
    if(!cur)return 0;///直接返回0
    //cout<<root<<" pre "<<ch[root][0]<<endl;
    while(ch[cur][1])
    {
        cur=ch[cur][1];
    }
    return cur;

}
int succ(int x)
{
    find(x);
    int cur=ch[root][1];
    if(!cur)return 0;
    //cout<<root<<" pre "<<ch[root][1]<<endl;
    while(ch[cur][0])
    {
        cur=ch[cur][0];
    }
    return cur;

}
void dfs(int cur)
{
    //cout<<cur<<"cur"<<" ch "<<ch[cur][1]<<endl;
    if(ch[cur][0])dfs(ch[cur][0]);
    cout<<val[cur]<<" "<<dat[cur]<<'\n';
    if(ch[cur][1])dfs(ch[cur][1]);
}
void del(int x)
{
    //cout<<root<<"END"<<endl;
    int p=pre(x),s=succ(x);///后缀为0???前驱为0???
    // cout<<p<<" PS "<<s<<endl;

    if(!s)
    {
        if(!p)
        {
            ch[root][0]=ch[root][1]=root=0;///只有一个点
            return;
        }

        splay(p);///没有后缀
        ch[root][1]=0;
        return;
    }///???
    //cout<<x<<endl;
    //cout<<p<<s<<endl;
    splay(p);
    splay(s,p);
    int de=ch[s][0];
    if(cnt[de]>1)
    {
        cnt[de]--;
        splay(de);
    }
    else
        ch[s][0]=0;
    //par[ch[root][1]]=root;
    //pushup(root);

}
void ins(int x,int d)
{
    int cur=root,p=0;///维护父节点信息
    while(cur&&(x!=val[cur]))
    {
        p=cur;
        cur=ch[cur][x>val[cur]];///>号
    }
    if(cur)
    {
        cnt[cur]++;
    }
    else
    {
        cur=++tot;
        //cout<<p<<"父亲"<<endl;
        if(p)ch[p][x>val[p]]=cur;///判一下p是否为0
        ch[cur][0]=ch[cur][1]=0;
        par[cur]=p;///注意维护下父节点
        val[cur]=x;
        dat[cur]=d;
        size[cur]=1;
        cnt[cur]=1;
        // dfs(root);

        splay(cur);
    }
    // cout<<"DFS"<<endl;
    //dfs(root);

}

int mi()
{
    int cur=root;
    if(!cur)return 0;
    while(ch[cur][0])
    {
        cur=ch[cur][0];
    }
    int ans=dat[cur];
    del(val[cur]);
    return ans;
}
int ma()
{
    int cur=root;
    if(!cur)return 0;
    while(ch[cur][1])
    {
        cur=ch[cur][1];
    }
    int ans=dat[cur];
    //cout<<ans<<endl;
    del(val[cur]);
    //dfs(root);
    return ans;
}
int main()
{
    int n,d,p;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0)break;
        else if(n==1)
        {
            scanf("%d%d",&d,&p);
            ins(p,d);
        }
        else if(n==2)
        {
            cout<<ma()<<'\n';

        }
        else if(n==3)
        {
            cout<<mi()<<'\n';
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/liulex/p/11253575.html
今日推荐