题目背景

四川2008NOI省选

题目描述

斜堆(skew heap)是一种常用的数据结构。它也是二叉树,且满足与二叉堆相

同的堆性质:每个非根结点的值都比它父亲大。因此在整棵斜堆中,根的值最小。

但斜堆不必是平衡的,每个结点的左右儿子的大小关系也没有任何规定。在本题

中,斜堆中各个元素的值均不相同。

在斜堆 H 中插入新元素X 的过程是递归进行的:当H 为空或者X 小于H

的根结点时X 变为新的树根,而原来的树根(如果有的话)变为X 的左儿子。

当X 大于H 的根结点时,H 根结点的两棵子树交换,而X(递归)插入到交换

后的左子树中。

给出一棵斜堆,包含值为0~n的结点各一次。求一个结点序列,使得该斜堆

可以通过在空树中依次插入这些结点得到。如果答案不惟一,输出字典序最小的

解。输入保证有解。

输入输出格式

输入格式:

第一行包含一个整数n。第二行包含n个整数d1, d2, ... , dn, di<100表示i

是di的左儿子,di>=100 表示i 是di-100 的右儿子。显然0 总是根,所以输入中

不含d0。

输出格式:

仅一行,包含n+1整数,即字典序最小的插入序列。

输入输出样例

输入样例#1:

  1. 6
  2. 100 0 101 102 1 2
输出样例#1:

  1. 0 1 2 3 4 5 6
输入样例#2:

  1. 6
  2. 100 0 2 102 4 104
输出样例#2:

  1. 4 6 5 2 0 1 3
输入样例#3:

  1. 7
  2. 0 100 1 102 2 3 5
输出样例#3:

  1. 2 5 0 3 4 6 7 1

说明

2 <= n <= 50

Solution:

  这题,ZYYS~,真人类智慧题啊。

  %%%Mato  

  考虑斜堆中最后插入的那个结点,容易发现:
(1)它一定是一个极左结点(就是从根往它的路上一直都是沿着左链走),因为插入的时候每次都是插入到左子树中;
(2)它一定木有右子树,因为插入的时候每次都是把原来的某棵子树作为新结点的左子树;

满足(1)(2)的结点可能有多个,但紧接着可以发现,这个斜堆中的每个结点如果木有左子结点,那么也木有右子结点(或者说,每个非叶结点都有左子树),而在插入一个结点之前,其所有的祖先都被交换了左右子树,所以,若新结点的祖先中有满足(1)(2)的,且新结点不是叶结点,那么在新结点插入之前,这个满足(1)(2)的祖先必然是只有右子树而木有左子树的,这与上面的那个性质矛盾,所以,可以得出:最后插入的那个结点一定是满足(1)(2)的结点中,深度最小的那个(设为X),除非X的左子结点是叶结点,此时为了满足字典序最小,应该取X的左子结点为最后插入的。找到这个最后插入的结点以后,只需要把它删掉,并把它的所有祖先交换左右子树,就是插入该结点以前的状态了。这样可以找到字典序最小的插入顺序。

  (反正我自己是想不出的>.^_^.<)

代码:

  1. /*Code by 520 -- 8.28*/
  2. #include<bits/stdc++.h>
  3. #define il inline
  4. #define ll long long
  5. #define RE register
  6. #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
  7. #define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
  8. using namespace std;
  9. const int N=;
  10. int n,rt,fa[N],ls[N],rs[N],ans[N],cnt;
  11.  
  12. il void pre(){
  13. memset(fa,-,sizeof(fa)),
  14. memset(ls,-,sizeof(ls)),
  15. memset(rs,-,sizeof(rs));
  16. }
  17.  
  18. il void init(){
  19. int x=rt;
  20. while(rs[x]!=-) x=ls[x];
  21. int t=ls[x];
  22. if(t!=-&&ls[t]==-&&rs[t]==-) x=t;
  23. ans[++cnt]=x;
  24. if(x==rt) rt=ls[x];
  25. int f=fa[x];
  26. if(f!=-) ls[f]=ls[x],fa[ls[f]]=f;
  27. while(f!=-) swap(ls[f],rs[f]),f=fa[f];
  28. }
  29.  
  30. int main(){
  31. pre();
  32. scanf("%d",&n);
  33. For(i,,n) {
  34. RE int x;scanf("%d",&x);
  35. if(x<) ls[x]=i,fa[i]=x;
  36. else rs[x-]=i,fa[i]=x-;
  37. }
  38. For(i,,n) init();
  39. while(cnt) printf("%d ",ans[cnt--]);
  40. return ;
  41. }

P2475 [SCOI2008]斜堆的更多相关文章

  1. P2475 [SCOI2008]斜堆(递归模拟)

    思路 可并堆真是一种神奇的东西 不得不说这道题是道好题,虽然并不需要可并堆,但是能加深对可并堆的理解 首先考虑斜堆的性质,斜堆和左偏树相似,有如下的性质 一个节点如果有右子树,就一定有左子树 最后插入 ...

  2. BZOJ 1078: [SCOI2008]斜堆

    1078: [SCOI2008]斜堆 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 770  Solved: 422[Submit][Status][ ...

  3. 【bzoj1078】[SCOI2008]斜堆

    2016-05-31 16:34:09 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1078 挖掘斜堆的性质233 http://www.cp ...

  4. 【BZOJ1078】[SCOI2008]斜堆(性质题)

    [BZOJ1078][SCOI2008]斜堆(性质题) 题面 BZOJ 洛谷 题解 考虑一下这道题目的性质吧.思考一下最后插入进来的数是什么样子的.首先因为它是最后插入进来的,所以一定是比某个数小,然 ...

  5. 【BZOJ 1078】 1078: [SCOI2008]斜堆

    1078: [SCOI2008]斜堆 Description 斜堆(skew heap)是一种常用的数据结构.它也是二叉树,且满足与二叉堆相同的堆性质:每个非根结点的值都比它父亲大.因此在整棵斜堆中, ...

  6. [SCOI2008]斜堆

    题目大意 1.题目描述 斜堆(skew heap)是一种常用的数据结构. 它也是二叉树,且满足与二叉堆相同的堆性质: 每个非根结点的值都比它父亲大.因此在整棵斜堆中,根的值最小. . 但斜堆不必是平衡 ...

  7. BZOJ1078 [SCOI2008]斜堆 堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1078 题意概括 斜堆(skew heap)是一种常用的数据结构.它也是二叉树,且满足与二叉堆相同的 ...

  8. 【bzoj1078】 SCOI2008—斜堆

    http://www.lydsy.com/JudgeOnline/problem.php?id=1078 (题目链接) 题意 给出一个斜堆,并给出其插入的操作,求一个字典序最小的插入顺序. Solut ...

  9. [bzoj1078][SCOI2008][斜堆] (贪心)

    Description 斜堆(skew heap)是一种常用的数据结构.它也是二叉树,且满足与二叉堆相同的堆性质:每个非根结点的值都比它父亲大.因此在整棵斜堆中,根的值最小.但斜堆不必是平衡的,每个结 ...

随机推荐

  1. 【Todo】找出共同好友 & Spark & Hadoop面试题

    找了这篇文章看了一下面试题<Spark 和hadoop的一些面试题(准备)> http://blog.csdn.net/qiezikuaichuan/article/details/515 ...

  2. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言(内容已过期,阅读请慎重)

    2018-09-19 更新 :现在已经更新ASP.NET Core Middleware版本.对.NET Core SignalR感兴趣的朋友移步:https://github.com/fanpan2 ...

  3. Maven学习(十六)-----Maven插件

    Maven插件 Maven 是一个执行插件的框架,每一个任务实际上是由插件完成的.Maven 插件通常用于: 创建 jar 文件 创建 war 文件 编译代码文件 进行代码单元测试 创建项目文档 创建 ...

  4. 手摸手,和你一起学习 UiPath Studio

    学习 RPA 的路上坑比较多,让我们手摸手,一起走…… 以下是一些学习 UiPath 和 RPA 的资源, 拿走不用谢! UiPath Studio 中文文档 机器人流程自动化其实是很好的概念和技术, ...

  5. katalon系列八:Katalon Studio图片识别

    Katalon Studio自带集成了图片识别功能,有2个比较有用的图片识别相关的命令:Wait For Image Present和Click Image.这里重点讲下Click Image命令: ...

  6. VS2013只显示会附加到进程,无法启动调试

    今天在使用VS2013的时候,打开突然发现,只显示附加到进程,无法进行调试,调试位置显示灰色,到网上各处寻求答案,本以为是个大问题,没想到只是个小问题.主要原因只是后台开太多东西了,导致VS2013运 ...

  7. 网络流dinic模板,邻接矩阵+链式前向星

    //这个是邻接矩阵的#include<iostream> #include<queue> #include<string.h> #include<stdio. ...

  8. Educational Codeforces Round 63 D. Beautiful Array

    D. Beautiful Array time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  9. SQL判断是否存在

    判断数据库是否存在 ifexists(select*frommaster..sysdatabaseswherename=N’库名’) print’exists’ else print’notexist ...

  10. 曾经我是一个只会excel的数据分析师,直到我遇到了……

    我是一个数据分析师. 准确来说我是一个当年只会excel数据透视表,就天不怕地不怕地来当数据分析师的人.当年的某一天,我的老板Q我: 小刘啊,我小姨子给了我一个全国市委书记的名单,你帮我看看,有什么规 ...