bzoj 1078 [SCOI2008]斜堆 —— 斜堆

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1078

考察斜堆的性质;

一个点如果没有左子树,也一定没有右子树;

看了这篇精美的博客:http://www.cppblog.com/MatoNo1/archive/2013/03/03/192131.html

对斜堆有了更多认识。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int const maxn=1e5+5;
int n,rt,ls[maxn],rs[maxn],fa[maxn],ans[maxn];
int find(int x)
{
    while(rs[x]!=-1)x=ls[x];
    if(ls[x]!=-1&&ls[ls[x]]==-1)x=ls[x];
    return x;
}
void del(int x)
{
    if(x==rt)rt=ls[rt];//
    int f=fa[x];
    if(f!=-1)ls[f]=ls[x],fa[ls[x]]=f;//x 无右子树,且是极左点 
    while(f!=-1)swap(ls[f],rs[f]),f=fa[f];//-1
    ls[x]=rs[x]=fa[x]=-1; //-1
}
int main()
{
    scanf("%d",&n);
    memset(fa,-1,sizeof fa);
    memset(ls,-1,sizeof ls);
    memset(rs,-1,sizeof rs);
    for(int i=1,x;i<=n;i++)
    {
        scanf("%d",&x);
        if(x<100)ls[x]=i,fa[i]=x;
        else rs[x-100]=i,fa[i]=x-100;
    }
    for(int i=0;i<=n;i++)
    {
        ans[i]=find(rt); 
        del(ans[i]);
    }
    for(int i=n;i>=0;i--)printf("%d ",ans[i]);
    return 0;
}

 

posted @ 2018-09-07 15:44  Zinn  阅读(180)  评论(0编辑  收藏  举报