洛谷 P1377 [TJOI2011]树的序 解题报告

P1377 [TJOI2011]树的序

题目描述

众所周知,二叉查找树的形态和键值的插入顺序密切相关。准确的讲:1、空树中加入一个键值\(k\),则变为只有一个结点的二叉查找树,此结点的键值即为\(k\);2、在非空树中插入一个键值\(k\),若\(k\)小于其根的键值,则在其左子树中插入\(k\),否则在其右子树中插入\(k\)

我们将一棵二叉查找树的键值插入序列称为树的生成序列,现给出一个生成序列,求与其生成同样二叉查找树的所有生成序列中字典序最小的那个,其中,字典序关系是指对两个长度同为\(n\)的生成序列,先比较第一个插入键值,再比较第二个,依此类推。

输入输出格式

输入格式:

第一行,一个整数,\(n\),表示二叉查找树的结点个数。第二行,有\(n\)个正整数,\(k_1\)\(k_n\),表示生成序列,简单起见,\(k_1\)~\(k_n\)为一个1到\(n\)的排列。

输出格式:

一行,\(n\)个正整数,为能够生成同样二叉查找数的所有生成序列中最小的。

说明

对于20%的数据,n ≤ 10。

对于50%的数据,n ≤ 100。

对于100%的数据,n ≤ 100,000。


先化简一下模型,我们把\(BST\)树建好,然后输出中序遍历即是答案。

然而,直接建\(BST\)是很容易退化成链的。

做过题目多的人可能听说过,这个叫笛卡尔树

笛卡尔树是一种既满足堆性质又满足二叉排序树性质的树。

方法一:普通笛卡尔树的建树方法

现在有一个序列按二叉排序树的关键字\(Key\)从小到大有序,序列中包含小跟堆的关键字\(Index\)关键字,在\(O(N)\)的时间建树。

按原数列顺序一个一个将节点加入笛卡尔树,可以确定一定是从链的右边向下找到一个\(Index\)大于这个点的节点,把这个节点位置占据,然后置让Ta当自己的左儿子即可。

用栈把最右边的链存下来,栈顶为右边最底的那个点,加入时边弹出边向上找,更新好位置关系后把自己存进栈即可。

code:

#include <cstdio>
#include <algorithm>
#define ls t[now].ch[0]
#define rs t[now].ch[1]
#define f t[now].par
const int N=100010;
struct node
{int dat,index;bool friend operator <(node n1,node n2){return n1.dat<n2.dat;}
}a[N];
struct BST
{int ch[2],dat,index,par;//左右儿子,BST域,堆域,父亲
}t[N];
int tot=0,n,s[N];
void connect(int fa,int now,int typ)
{f=fa;t[fa].ch[typ]=now;
}
void dfs(int now)
{if(!now) return;printf("%d ",t[now].dat);dfs(ls);dfs(rs);
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",a+i);a[i].index=i;}std::sort(a+1,a+1+n);for(int i=1;i<=n;i++){int last=0;while(tot&&t[s[tot]].index>a[i].index)last=tot--;t[i].dat=a[i].dat;t[i].index=a[i].index;connect(s[tot],i,1);connect(i,s[last],0);s[++tot]=i;}dfs(t[0].ch[1]);return 0;
}

方法二:按堆性质自底向上建立。
这个方法好厉害,真的很强。

则如果两个点的\(Key\)在“当前”数值上的差最小,那么Ta俩一定有一条边。

\(Index\)从大到小建立笛卡尔树,则对\(1\)-\(Index-1\)的点中,是不会有\(Index\)的儿子的。

\(pre[i]\)\(suc[i]\)分别存储\(Key\)\(i\)的点在“当前”所相邻的前驱和后继。

每次处理完一个点,更新与它相连的“前驱”和“后继”,这对应了“当前”

注意到原数据为1到n的排列,可以用桶排,比较快。

Code:

#include <cstdio>
const int N=100010;
int a[N],b[N],L[N],R[N],pre[N],suc[N],n;
void dfs(int now)
{if(!now) return;printf("%d ",a[now]);dfs(L[now]);dfs(R[now]);
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",a+i);b[a[i]]=i;pre[i]=i-1,suc[i]=i+1;}for(int i=n;i>1;i--){int pree=pre[a[i]],succ=suc[a[i]];if(b[pree]>b[succ])R[b[pree]]=i;elseL[b[succ]]=i;suc[pree]=succ;pre[succ]=pree;}dfs(1);return 0;
}

2018.6.19

转载于:https://www.cnblogs.com/butterflydew/p/9199591.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/485808.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

不能编程、烧钱、没用?潘建伟直播回应“九章”量子计算争议

来源&#xff1a;腾讯科技在200秒时间内&#xff0c;76个光子穿过中国科学技术大学潘建伟团队精心构筑的光学网络&#xff0c;完成了5000万个样本的高斯玻色采样。而同样一道数学题交给世界上最顶尖 的超级计算机“富岳”&#xff0c;需要6亿年&#xff0c;差距超过了百万亿&a…

Leetcode--209. 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 s &#xff0c;找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组&#xff0c;返回 0。 示例: 输入: s 7, nums [2,3,1,2,4,3] 输出: 2 解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组…

java 继承类_java类的继承

继承就是在一个现有类型的基础上&#xff0c;通过增加新的方法或者重定义已有方法(重写)的方式&#xff0c;产生一个新的类型。继承是面向对 象的三个基本特征——封装、继承、多态的其中之一&#xff0c;我们在使用java时编写的每一个类都是在继承&#xff0c;因为在java语言 …

Leetcode--287. 寻找重复数

给定一个包含 n 1 个整数的数组 nums&#xff0c;其数字都在 1 到 n 之间&#xff08;包括 1 和 n&#xff09;&#xff0c;可知至少存在一个重复的整数。假设只有一个重复的整数&#xff0c;找出这个重复的数。 示例 1: 输入: [1,3,4,2,2] 输出: 2 示例 2: 输入: [3,1,3,4…

2021年,神经科学AI有这几大趋势

来源&#xff1a;The Next Web作者&#xff1a;Tristan Greene编译&#xff1a;科技行者新的一年正向我们招手。延续优良的革命传统&#xff0c;又到了发布最新一期AI专家预测报告的时候。各位受访专家将结合自己的所感所知、实验室发现以及企业动态为我们预测新一年中人工智能…

深度遍历和广度遍历

深度优先 例如下图&#xff0c;其深度优先遍历顺序为 1->2->4->8->5->3->6->7 广度优先 如下图&#xff0c;其广度优先算法的遍历顺序为&#xff1a;1->2->3->4->5->6->7->8 转载于:https://www.cnblogs.com/bigman-bugman/p/920252…

java ejb项目_Maven创建EJB项目结构

可以用maven创建EJB项目的结构。1、打开cmd2、输入一下内容mvn archetype:generate -DarchetypeGroupIdorg.codehaus.mojo.archetypes -DarchetypeArtifactIdpom-root -DarchetypeVersion1.1 -DarchetypeRepositoryhttp://repo.maven.apache.org/maven2 -DgroupIdcom.XXX -Dart…

2020年人工智能十大技术进展

pixabay.com来源&#xff1a;知识分子 撰文 &#xff1a; 全体智源学者制版编辑&#xff1a;卢卡斯编者按编者按2020年即将过去&#xff0c;今年人工智能领域有哪些重大进展&#xff1f;位于北京的智源人工智能研究院请 “智源学者” 们从全球的研究成果中评选了一份年度成就名…

Leetcode--424. 替换后的最长重复字符

给你一个仅由大写英文字母组成的字符串&#xff0c;你可以将任意位置上的字符替换成另外的字符&#xff0c;总共可最多替换 k 次。在执行上述操作后&#xff0c;找到包含重复字母的最长子串的长度。 注意: 字符串长度 和 k 不会超过 104。 示例 1: 输入: s "ABAB"…

CentOS 6快捷安装RabbitMQ教程

1.安装Erlang yum install erlang 2.安装RabbitMQ yum install rabbitmq-server 3.配置开机自启动 chkconfig rabbitmq-server on 4.启动RabbitMQ service rabbitmq-server start 5.查询RabbitMQ路径 whereis rabbitmq 6.进入目录 7.开启RabbitMQ的Web管理界面 ./rabbitmq-plug…

java视频压缩 lz4_关于LZMA和LZ4压缩的疑惑解析

原标题&#xff1a;关于LZMA和LZ4压缩的疑惑解析这是第112篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题&#xff0c;建议阅读时间10分钟&#xff0c;认真读完必有收获。UWA QQ群&#xff1a;465082844(仅限技术交流)AssetBundleQ&#xff1a;…

微积分的发现是人类精神的最高胜利

来源 &#xff1a; 数学英才微积分早期的思想基础在25岁以前的伽利略就开始作了一系列实验&#xff0c;发现了许多有关物体在地球引力场运动的基本事实&#xff0c;最基本的就是自由落体定律。开普勒在1619年前后归纳为著名的行星运动三大定律。这些成就对后来的绝大部份的数学…

数据库MySQL/mariadb知识点——触发器

触发器 触发器&#xff1a;trigger&#xff0c;是指事先为某张表绑定一段代码&#xff0c;当表中的某些内容发生改变&#xff08;增、删、改&#xff09;的时候&#xff0c;系统会自动触发代码并执行。 触发器包含三个要素&#xff0c;分别为 事件类型&#xff1a;增删改&#…

Leetcode--826. 安排工作以达到最大收益

有一些工作&#xff1a;difficulty[i] 表示第i个工作的难度&#xff0c;profit[i]表示第i个工作的收益。 现在我们有一些工人。worker[i]是第i个工人的能力&#xff0c;即该工人只能完成难度小于等于worker[i]的工作。 每一个工人都最多只能安排一个工作&#xff0c;但是一个…

【前沿技术】2021九大技术趋势:规模化机器学习、「零信任」架构

来源&#xff1a;智能研究院《德勤2021年技术趋势》报告研究了疫情一年来对企业战略、运营和技术带来的连锁反应&#xff0c;论述了其重大发现&#xff1a;全球企业正在加速数字化战略转型&#xff0c;从而构建「韧性」、开创全新的经营模式。报告讨论了接下来18至24个月及以后…

Java项目打包成exe的详细教程

Java项目打包成exe的详细教程 把Java项目打包成exe共分为以下两步&#xff1a; 1、 利用Eclipse先把Java项目先打成jar包 2、 利用exe4j工具把jar包转成exe 这里以Java项目&#xff08;ExeDemo&#xff09;为例进行讲解 随便在一个位置新建一个文件夹&#xff0c;文件夹的名称也…

linux java amr转mp3_本工具用于将微信语音 amr 格式转换为 mp3 格式以便在 html5 的 audio 标签中进行播放...

音频转码工具本工具主要用于将微信语音 amr 格式转换为 mp3 格式以便在 html5 的 audio 标签中进行播放。支持 Linux/Windows/Mac 平台因为是基于 JAVE 项目的修改&#xff0c;而 JAVE 是依赖 ffmpeg 所以可以适用于所有 ffmpeg 所支持的文件格式的转换。具体可以查看 JAVE 官方…

MySQL小问题:cant connect to MYSQL server on localhost

连接数据库发现出现了错误&#xff1a;2003-cant connext to MYSQL server on localhost 解决方法&#xff1a; 1.winr 打开cmd控制台&#xff0c;首先net startenter 查看有没有mysql服务启动&#xff0c;一般这不会出现问题 此时你输入mysql -u root -p 是会出现错误的 2…

【c# 学习笔记】所有类的父类:System.object

在c#中&#xff0c;所有的类都派生自System.Object类。如果定义的类&#xff0c;没有直达任何基类&#xff0c;编译器就会自动把Object类当作它的基类。和其他类 一样&#xff0c;System.Object类也定义了一组共有的成员&#xff0c;其定义如下&#xff1a; public class Objec…

数学史上的哲学绝唱——无穷观与数学基础的争论

来源&#xff1a;《广西民族大学学报》2014年11月作者&#xff1a;郭龙先&#xff0c;黄永两千多年来&#xff0c;数学家们一直试图从少数公理出发&#xff0c;根据明确给出的演绎规则推导出其他数学定理&#xff0c;从而把整个数学构造成为一个严密的演绎大厦&#xff0c;然后…