bzoj1078

题解:

一道思路题(话说在那个时候有多少人知道左偏树)

考虑最后一个加进来的点

必然满足

(1)从它到根一直是左链上去的

(2)没有左右子树

在这些点中寻找一个最浅的

然后删除

代码:

#include<bits/stdc++.h> 
using namespace std;
const int N=105;
int n,top,root,ls[N],rs[N],fa[N],x,ans[N];
void solve()
{
    int x=root;
    while (rs[x]!=-1)x=ls[x];
    int t=ls[x];
    if (t!=-1&&ls[t]==-1&&rs[t]==-1)x=t;
    ans[++top]=x;
    if (x==root)root=ls[root];
    int f=fa[x];
    if (f!=-1)ls[f]=ls[x],fa[ls[f]]=f;
    while (f!=-1)swap(ls[f],rs[f]),f=fa[f];
}
int main()
{
    fa[0]=-1;
    memset(ls,-1,sizeof(ls));
    memset(rs,-1,sizeof(rs));
    scanf("%d",&n);
    for (int i=1;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=1;i<=n+1;i++)solve();
    while (top)printf("%d ",ans[top--]);
    return 0;
}
原文地址:https://www.cnblogs.com/xuanyiming/p/8454843.html