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