P2475 [SCOI2008]斜堆
题目背景
四川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整数,即字典序最小的插入序列。
输入输出样例
6
100 0 101 102 1 2
0 1 2 3 4 5 6
6
100 0 2 102 4 104
4 6 5 2 0 1 3
7
0 100 1 102 2 3 5
2 5 0 3 4 6 7 1
说明
2 <= n <= 50
Solution:
这题,ZYYS~,真人类智慧题啊。
考虑斜堆中最后插入的那个结点,容易发现:
(1)它一定是一个极左结点(就是从根往它的路上一直都是沿着左链走),因为插入的时候每次都是插入到左子树中;
(2)它一定木有右子树,因为插入的时候每次都是把原来的某棵子树作为新结点的左子树;
满足(1)(2)的结点可能有多个,但紧接着可以发现,这个斜堆中的每个结点如果木有左子结点,那么也木有右子结点(或者说,每个非叶结点都有左子树),而在插入一个结点之前,其所有的祖先都被交换了左右子树,所以,若新结点的祖先中有满足(1)(2)的,且新结点不是叶结点,那么在新结点插入之前,这个满足(1)(2)的祖先必然是只有右子树而木有左子树的,这与上面的那个性质矛盾,所以,可以得出:最后插入的那个结点一定是满足(1)(2)的结点中,深度最小的那个(设为X),除非X的左子结点是叶结点,此时为了满足字典序最小,应该取X的左子结点为最后插入的。找到这个最后插入的结点以后,只需要把它删掉,并把它的所有祖先交换左右子树,就是插入该结点以前的状态了。这样可以找到字典序最小的插入顺序。
(反正我自己是想不出的>.^_^.<)
代码:
/*Code by 520 -- 8.28*/
#include<bits/stdc++.h>
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=;
int n,rt,fa[N],ls[N],rs[N],ans[N],cnt; il void pre(){
memset(fa,-,sizeof(fa)),
memset(ls,-,sizeof(ls)),
memset(rs,-,sizeof(rs));
} il void init(){
int x=rt;
while(rs[x]!=-) x=ls[x];
int t=ls[x];
if(t!=-&&ls[t]==-&&rs[t]==-) x=t;
ans[++cnt]=x;
if(x==rt) rt=ls[x];
int f=fa[x];
if(f!=-) ls[f]=ls[x],fa[ls[f]]=f;
while(f!=-) swap(ls[f],rs[f]),f=fa[f];
} int main(){
pre();
scanf("%d",&n);
For(i,,n) {
RE int x;scanf("%d",&x);
if(x<) ls[x]=i,fa[i]=x;
else rs[x-]=i,fa[i]=x-;
}
For(i,,n) init();
while(cnt) printf("%d ",ans[cnt--]);
return ;
}
P2475 [SCOI2008]斜堆的更多相关文章
- P2475 [SCOI2008]斜堆(递归模拟)
思路 可并堆真是一种神奇的东西 不得不说这道题是道好题,虽然并不需要可并堆,但是能加深对可并堆的理解 首先考虑斜堆的性质,斜堆和左偏树相似,有如下的性质 一个节点如果有右子树,就一定有左子树 最后插入 ...
- BZOJ 1078: [SCOI2008]斜堆
1078: [SCOI2008]斜堆 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 770 Solved: 422[Submit][Status][ ...
- 【bzoj1078】[SCOI2008]斜堆
2016-05-31 16:34:09 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1078 挖掘斜堆的性质233 http://www.cp ...
- 【BZOJ1078】[SCOI2008]斜堆(性质题)
[BZOJ1078][SCOI2008]斜堆(性质题) 题面 BZOJ 洛谷 题解 考虑一下这道题目的性质吧.思考一下最后插入进来的数是什么样子的.首先因为它是最后插入进来的,所以一定是比某个数小,然 ...
- 【BZOJ 1078】 1078: [SCOI2008]斜堆
1078: [SCOI2008]斜堆 Description 斜堆(skew heap)是一种常用的数据结构.它也是二叉树,且满足与二叉堆相同的堆性质:每个非根结点的值都比它父亲大.因此在整棵斜堆中, ...
- [SCOI2008]斜堆
题目大意 1.题目描述 斜堆(skew heap)是一种常用的数据结构. 它也是二叉树,且满足与二叉堆相同的堆性质: 每个非根结点的值都比它父亲大.因此在整棵斜堆中,根的值最小. . 但斜堆不必是平衡 ...
- BZOJ1078 [SCOI2008]斜堆 堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1078 题意概括 斜堆(skew heap)是一种常用的数据结构.它也是二叉树,且满足与二叉堆相同的 ...
- 【bzoj1078】 SCOI2008—斜堆
http://www.lydsy.com/JudgeOnline/problem.php?id=1078 (题目链接) 题意 给出一个斜堆,并给出其插入的操作,求一个字典序最小的插入顺序. Solut ...
- [bzoj1078][SCOI2008][斜堆] (贪心)
Description 斜堆(skew heap)是一种常用的数据结构.它也是二叉树,且满足与二叉堆相同的堆性质:每个非根结点的值都比它父亲大.因此在整棵斜堆中,根的值最小.但斜堆不必是平衡的,每个结 ...
随机推荐
- zabbix最新版3.4搭建(根据官方文档适当修改)
操作系统:CentOS Linux release 7.4.1708 (Core) 1.安装apache 1.1 安装apache yum install httpd httpd-devel 1.2 ...
- [转]资深CTO:关于技术团队打造与管理的10问10答
一.你如何衡量软件工程师个人的工作表现?如何衡量整个工程师团队的工作表现? 主要从两方面: 这个员工做的工作是不是他同意做的或者应该做的?(What) 他们是如何完成自己的工作的?(How) 任何绩效 ...
- (三)Hololens Unity 开发之 语音识别
学习源于官方文档 Voice input in Unity 笔记一部分是直接翻译官方文档,部分各人理解不一致的和一些比较浅显的保留英文原文 (三)Hololens Unity 开发之 语音识别 Hol ...
- python环境通过selenium实现自动化web登陆及终端邀请
自动化主要的就是识别对象,可以在网上搜到各种各样的方法,自行百度.下面仅附上一个简单的例子. 环境搭建参考如下链接: https://www.cnblogs.com/hepeilinnow/p/101 ...
- 第七篇 Postman+Node.js+Newman+Jenkins实现自动化测试
今天终于不咋忙了,学习整理一下一直想做却没实现的事儿,这事已经折磨团队半年之久了.因为项目是B端业务的测试,测试过程中需要生产大量的测试数据,而且都是跨多个系统的测试,对于后置流程的测试,这些同学往往 ...
- 【CentOS】安装Docker教程
前提条件 Docker 运行在 CentOS 7 上,要求系统为64位.系统内核版本为 3.10 以上. Docker 运行在 CentOS-6.5 或更高的版本的 CentOS 上,要求系统为64位 ...
- Valgrind 简单用法
有时需要给自己写的小程序做个简单的 benchmark,查看内存使用情况和运行时间.这时可以试试 valgrind. Ubuntu 下安装很简单: sudo apt-get update sudo a ...
- 华为笔试——C++括号匹配
题目:括号匹配 题目来源:https://blog.csdn.net/lizi_stdio/article/details/76618908 题目介绍:输入一个字符串,里面可能包含“()”.“ [ ...
- Linux下文件的打包、解压缩指令——tar,gzip,bzip2
本文是对 鸟叔的Linux私房菜(基础学习篇) 第三版 的学习笔记,原文可参考原书中文网站 鸟叔的Linux私房菜.更多详细信息可直接参考对应Linux命令的 man 帮助( 如 man tar). ...
- Immutable 常用API简介
本文主要整理了Immutable.js常用API的使用. Immutable 是什么? 关于Immutable的定义,官方文档是这样说的: Immutable data encourages pure ...