洛谷 P1377 [TJOI2011]:树的序 ← 笛卡尔树

【题目来源】
https://www.luogu.com.cn/problem/P1377

【题目描述】
众所周知,二叉查找树的形态和键值的插入顺序密切相关。准确的讲:
1.空树中加入一个键值 k,则变为只有一个结点的二叉查找树,此结点的键值即为 k。
2.在非空树中插入一个键值 k,若 k 小于其根的键值,则在其左子树中插入 k,否则在其右子树中插入 k。
我们将一棵二叉查找树的键值插入序列称为
树的生成序列现给出一个生成序列,求与其生成同样二叉查找树的所有生成序列中字典序最小的那个,其中,字典序关系是指对两个长度同为 n 的生成序列,先比较第一个插入键值,再比较第二个,依此类推。

【输入格式】
第一行,一个整数 n,表示二叉查找树的结点个数。
第二行,有 n 个正整数 k1,k2,⋯,kn,表示生成序列,简单起见,k1∼kn 为一个 1 到 n 的排列。

【输出格式】
一行,n 个正整数,为能够生成同样二叉查找树的所有生成序列中最小的。

【输入样例】
4
1 3 4 2

【输出样例】
1 3 2 4

【数据范围及约定】
对于 20% 的数据,1≤n≤10。
对于 50% 的数据,1≤n≤100。
对于 100% 的数据,1≤n≤10^5。

【算法分析】
● 题目中所提及到的“现给出一个生成序列,求与其生成同样二叉查找树的所有生成序列中字典序最小的那个”是一个必须理清的关键。意思是说,存在多个序列,能生成同样的二叉查找树,需输出字典序最小的那个。如本题样例中,1 3 4 2 与 1 3 2 4 都能够生成同样的二叉查找树,但 1 3 2 4 的字典序更小,所以输出了 1 3 2 4。
那么本题如何保证输出字典序最小的序列呢?由题设的构建条件知,所构建的二叉查找树的所有子树结点值相对于根结点而言都满足“
左小右大”的规则,因此对其进行先序遍历便能得到字典序最小的序列。
例如,按照题设规则,即“左小右大”规则,对本题样例 1,3,4,2 构建生成的二叉查找树如下所示。
然后,对此图进行
先序遍历,可得到字典序最小的输出 1,3,2,4。

● 本题可采用笛卡尔树进行求解。笛卡尔树结构由 Vuillmin(1980) 在解决范围搜索的几何数据结构问题时提出。笛卡尔树是一种非常特殊的二叉查找树(BST)。每个结点有两个信息 (pri, val),如果只考虑 pri,它是一棵二叉查找树,如果只考虑 val,它是一个小根堆。其中,pri 是结点插入顺序,或称优先级。val 是结点的值。也就是说,笛卡尔树具有二叉查找树和堆的双重特性

● 如何构建笛卡尔树?(参考于:https://wansuanfa.com/index.php/776
笛卡尔树的构建步骤如下:(构建前需对 pri 递增排序,或选择数组元素的默认递增下标)
(1)用数组中的第一个元素创建根结点。
(2)遍历数组中剩下的元素,如果新元素比根结点小,让根结点成为新结点的左子结点,然后新结点成为根结点。
(3)如果新结点比根结点大,就从根结点沿着最右边这条路径一种往右走,直到找到比新结点大的结点 node ,也可能没找到。如果找到,就让新结点替换 node 结点的位置,让 node 结点变成新结点的左子结点。如果没找到,就让新结点成为最后查找的那个结点的右子结点。
(4)重复上面步骤(2),(3),直到元素全部遍历完。

● 构建笛卡尔树的关键点解析(参考于:
https://wansuanfa.com/index.php/776
(1)如果新结点比根结点小,根据小根堆(元素的值满足小根堆)的性质,那么新结点一定是根结点的父节点。又因为根结点的下标比新结点小,根据二叉查找树(元素的下标满足二叉查找树)的性质,根结点只能是新结点的左子树。
(2)如果新结点比根结点大,那么新结点只能往右边查找,不能往左边,如果往左边就不满足二叉查找树的性质了。如果比右子结点还大,就继续往右,所以只要比右子结点大就会一直往右。如果比右子结点小,根据小根堆的性质,新结点就会成为这个右子结点的父结点,根据二叉查找树的性质,这个右子结点要成为新结点的左子结点(因为右子结点的下标比新结点小)。

下图为构建笛卡尔树的过程示意图。通过构建过程,易知如何维护笛卡尔树每个结点的两个信息 
(pri, val),以及如何保障笛卡尔树具有二叉查找树和堆的双重特性。由图可知,构建方法为以 val 值作为结点,并用其构建小根堆。当需要调整时,以结点插入顺序(或称优先级 pri)为依据,将对应结点置于左子树或右子树,从而保证“如果只考虑 pri,它是一棵二叉查找树”的特性。
简言之,一棵笛卡尔树,结点的值为 val,结点的位置为 pri 所致。



● 单调栈:https://blog.csdn.net/hnjzsyjyj/article/details/117370314
单调栈是一种非常适合处理“下一个更大元素(Next Greater Number)”问题的数据结构。
笛卡尔树的构建过程中,常还需借助“
单调栈”这种数据结构,以保证在线性时间内完成笛卡尔树的构建。单调栈中保存的始终是笛卡尔树的右链,即由笛卡尔树的“根结点、根结点的右儿子、根结点的右儿子的右儿子、……”组成的链。并且,为了维护笛卡尔树的小根堆特性,单调栈中的元素值从栈顶到栈底需依次递减,且栈底存储的是根结点。由于每个元素最多进出站各一次,所以时间复杂度为 O(n)。

● 快读:https://blog.csdn.net/hnjzsyjyj/article/details/120131534
在数据量比较大的时候,即使使用 scanf 函数读入数据也会超时,这时就需要使用“快读”函数了。“快读”函数之所以快,是因为其中的
getchar 函数要比 scanf 函数快。 网传,“快读”函数能以比 scanf 函数快5倍的速度读入任意整数
貌似,笛卡尔树问题常用到快读。

● 本题代码与 https://blog.csdn.net/hnjzsyjyj/article/details/138353654 及其相似,可对比学习。

【算法代码】

#include <bits/stdc++.h>
using namespace std;typedef long long LL;
const int maxn=1e5+5;int a[maxn];
int n;
LL lson[maxn],rson[maxn];stack<int> s;int read() { //fast readint x=0,f=1;char c=getchar();while(c<'0' || c>'9') { //!isdigit(c)if(c=='-') f=-1; //- is a minus signc=getchar();}while(c>='0' && c<='9') { //isdigit(c)x=x*10+c-'0';c=getchar();}return x*f;
}void print(int x) {if(x==0) return;cout<<x<<" ";print(lson[x]);print(rson[x]);
}int main() {scanf("%d",&n);for(int i=1; i<=n; i++) {int id;id=read();a[id]=i;}for(int i=1; i<=n; i++) {while(!s.empty() && a[s.top()]>a[i]) {lson[i]=s.top();s.pop();}if(!s.empty()) rson[s.top()]=i;s.push(i);}int root;while(!s.empty()) {root=s.top();s.pop();}print(root);return 0;
}/*
in:
4
1 3 4 2out:
1 3 2 4
*/




【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/138353654
https://blog.csdn.net/hnjzsyjyj/article/details/138353654
https://blog.csdn.net/liufengwei1/article/details/107866930
https://www.cnblogs.com/LSlzf/p/11150484.html
https://www.cnblogs.com/yinyuqin/p/15000037.html
https://zhuanlan.zhihu.com/p/674774129
https://wansuanfa.com/index.php/776
https://blog.csdn.net/pi9nc/article/details/9388761
 

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

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

相关文章

智能物联网与Web3:连接未来数字生活的桥梁

随着科技的不断进步&#xff0c;智能物联网&#xff08;IoT&#xff09;和Web3技术正成为数字化时代的关键驱动力。智能物联网将各种物理设备连接到互联网&#xff0c;使其能够感知环境、收集数据并与其他设备通信&#xff0c;而Web3技术则以去中心化、安全性和透明性为核心&am…

Linux开发板 FTP 服务器移植与搭建

VSFTPD&#xff08;Very Secure FTP Daemon&#xff09;是一个安全、稳定且快速的FTP服务器软件&#xff0c;广泛用于Unix和Linux操作系统。它以其轻量级、高效和易于配置而受到赞誉。VSFTPD不仅支持标准的FTP命令和操作&#xff0c;还提供了额外的安全特性&#xff0c;如匿名F…

Python日志记录库之logbook使用详解

概要 在软件开发和运维中,日志记录是一项至关重要的任务。Python 的 Logbook 库是一个强大而灵活的日志记录工具,提供了丰富的功能和易用的接口。本文将深入探讨 Logbook 库的特性、用法,并通过丰富的示例代码展示其在实际项目中的应用。 Logbook 简介 Logbook 是一个为 P…

本地搭建llama大模型及对话UI

环境说明&#xff1a;MBP 2023 M2Pro芯片 用到的工具/组件/技术&#xff1a;ollama、llama3:8b、docker、open-webui 1.下载ollama ollama官网下载地址&#xff1a;https://ollama.com/download 到ollama官网地址下载对应操作系统版本的ollama平台&#xff0c;按照安装指引…

springboot 获取maven打包时间

springboot 获取maven打包时间 pom <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.13.RELEASE</version><relativePath /> <!-- lookup parent…

民航电子数据库:mysql与cae(insert语法差异)

目录 示例1、cae插入数据时不支持value关键字&#xff0c;只能使用values2、insert时&#xff0c;就算是自增主键&#xff0c;只要新增时包含了主键&#xff0c;该主键就必须有值&#xff0c;否则会报错&#xff1a;字段xxx不能取空值 对接民航电子数据库&#xff0c;本篇记录i…

用栈实现队列——leetcode刷题

题目要求我们只用栈的基本操作 push to top 入栈&#xff0c;peek from top 返回栈顶元素&#xff0c;pop from top 移除并返回栈顶元素&#xff0c;size 栈的大小&#xff0c;is_empty 判断栈是否为空&#xff0c;这几个函数来实现队列&#xff0c;也就是说&#xff0c;我们在…

salesforce 如何访问lwc组件

访问lwc有哪些途径呢? Action ButtonTabAura use lwc(拓展)如何区分是新建页面还是编辑页面 Action Button xml文件中要配置tab<?xml version"1.0" encoding"UTF-8"?> <LightningComponentBundle xmlns"http://soap.sforce.com/2006/04/…

全景剖析阿里云容器网络数据链路(七):Terway DataPath V2(Terway≥1.8.0)

作者&#xff1a;余凯 前言 近几年&#xff0c;企业基础设施云原生化的趋势越来越强烈&#xff0c;从最开始的IaaS化到现在的微服务化&#xff0c;客户的颗粒度精细化和可观测性的需求更加强烈。容器网络为了满足客户更高性能和更高的密度&#xff0c;也一直在高速的发展和演…

Docker 简单使用及安装常用软件

一、Docker 安装、配置与卸载 1.1、Docker 安装 # 1.安装gcc环境 yum -y install gcc gcc-c && \# 2. 卸载docker旧版本&#xff08;可能之前有安装&#xff09; yum -y remove docker docker-common docker-selinux docker-engine && \# 3. 安装依赖的软件包…

PHP源码_最新在线工具箱网站系统源码

项目运行截图 源码贡献 https://githubs.xyz/boot?app41 部分数据库表 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;-- ---------------------------- -- Table structure for toolbox_category -- ---------------------------- DROP TABLE IF EXISTS toolbox_category…

Golang | Leetcode Golang题解之第64题最小路径和

题目&#xff1a; 题解&#xff1a; func minPathSum(grid [][]int) int {if len(grid) 0 || len(grid[0]) 0 {return 0}rows, columns : len(grid), len(grid[0])dp : make([][]int, rows)for i : 0; i < len(dp); i {dp[i] make([]int, columns)}dp[0][0] grid[0][0]…

ubuntu sudo apt-get install neo4j 配置安装与设置远程访问

文章目录 下载Adding the Debian repositoryInstalling Neo4j安装流程设置远程访问 下载 neo4j 官方的下载地址&#xff0c;进入页面之后&#xff0c;往下滑&#xff1a; https://neo4j.com/deployment-center/#community 点击 Visit https://debian.neo4j.com/ Adding the …

Apache Seata基于改良版雪花算法的分布式UUID生成器分析1

title: Seata基于改良版雪花算法的分布式UUID生成器分析 author: selfishlover keywords: [Seata, snowflake, UUID] date: 2021/05/08 本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 Seata基于改良版雪花算法的分布式UUID生成器分析…

电子式汽车机油压力传感器的接线方法及特点

电子式机油压力传感器由厚膜压力传感器芯片、信号处理电路、外壳、固定电路板装置和两根引线&#xff08;信号线和报警线&#xff09;组成。信号处理电路由电源电路、传感器补偿电路、调零电路、电压放大电路、电流放大电路、滤波电路和报警电路组成。 厚膜压力传感器是20世纪…

数据结构 - C/C++

快速跳转 数组链表栈队列串树 目录 数据结构 逻辑结构 物理结构 数据结构 数据 数据不仅仅包括整型、实型等数值类型&#xff0c;还包括字符及声音、图像、视频等非数值类型。 计算机可以理解并按照指定格式处理。 结构 元素相互之间存在一种或多种特定关系的数据集合。 …

tuxera ntfs for mac是什么 tuxera ntfs for mac怎么用 tuxera激活码

Tuxera NTFS for Mac是一款完全的mac读写软件&#xff0c;可辅助mac电脑读写ntfs格式&#xff0c;进行磁盘的管理。本文会详细讲解tuxera ntfs for mac的操作方法。 Tuxera NTFS for Mac 2023安装包免费下载&#xff1a;https://souurl.cn/IE35lO 一、Tuxera NTFS for Mac是什…

goget配置多个golang 运行环境

一台主机安装多个golang 运行环境 本环境 windows10 为 基础 mac linux也可以按照此方法操作 背景 开发不同的运维工具会用到不同版本的golang&#xff0c;但是开发者不能一直进行重装来处理 &#xff0c;因此 需要一个工具进行golang版本的管理 go管理工具介绍 gvm (Go V…

微服务保护和分布式事务(Sentinel、Seata)笔记

一、雪崩问题的解决的服务保护技术了解 二、Sentinel 2.1Sentinel入门 1.Sentinel的安装 &#xff08;1&#xff09;下载Sentinel的tar安装包先 &#xff08;2&#xff09;将jar包放在任意非中文、不包含特殊字符的目录下&#xff0c;重命名为 sentinel-dashboard.jar &…

【C++报错】error C2143:语法错误:缺少“ : ”(在“<” 的前面)[ 相互引用问题 ]

这里写自定义目录标题 情景再现问题分析是经典的互相引用问题 解决方案 情景再现 问题分析 template<class K,class T,class KeyofT,class Hash>class __HTIterator{typedef HashNode<T> Node;typedef HashTable<K, T, KeyofT, Hash> HT; 【★】typedef …