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

洛谷 P1377 [TJOI2011]树的序 解题报告相关推荐

  1. P1377 [TJOI2011]树的序 笛卡尔树优化建树

    传送门 文章目录 题意: 思路: 题意: 给你一棵二叉树的生成序列,让你输出一个字典序最小的序列,使其生成的二叉树与原来的二叉树相同. 思路: 首先想到暴力建树,让后输出先序遍历即可,但是这样如果二叉 ...

  2. 洛谷 P3332 [ZJOI2013]K大数查询 解题报告

    P3332 [ZJOI2013]K大数查询 题目描述 有\(N\)个位置,\(M\)个操作.操作有两种,每次操作如果是\(\tt{1\ a\ b\ c}\)的形式表示在第\(a\)个位置到第\(b\) ...

  3. 洛谷 P3797 妖梦斩木棒 解题报告

    P3797 妖梦斩木棒 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的\(n\)段.现在这个木棒可以看做 ...

  4. 洛谷 P2114 [NOI2014]起床困难综合症 解题报告

    P2114 [NOI2014]起床困难综合症 题目描述 21世纪,许多人得了一种奇怪的病:起床困难综合症,其临床表现为:起床难,起床后精神不佳.作为一名青春阳光好少年,atm一直坚持与起床困难综合症作 ...

  5. 洛谷 P2463 [SDOI2008]Sandy的卡片 解题报告

    P2463 [SDOI2008]Sandy的卡片 题意 给\(n(\le 1000)\)串,定义两个串相等为"长度相同,且一个串每个数加某个数与另一个串完全相同",求所有串的最长公 ...

  6. 洛谷 P1356 数列的整数性 解题报告

    P1356 数列的整数性 题目描述 对于任意一个整数数列,我们可以在每两个整数中间任意放一个符号'+'或'-',这样就可以构成一个表达式,也就可以计算出表达式的值.比如,现在有一个整数数列:17,5, ...

  7. 洛谷 P2530 [SHOI2001]化工厂装箱员 解题报告

    P2530 [SHOI2001]化工厂装箱员 题目描述 118号工厂是世界唯一秘密提炼锎的化工厂,由于提炼锎的难度非常高,技术不是十分完善,所以工厂生产的锎成品可能会有3种不同的纯度,A:100%,B ...

  8. 一中OJ #3509 七的倍数 [USACO Jan16,洛谷P3131] | 同余前缀和 | 解题报告

    一中OJ | #3509 七的倍数 [USACO Jan16 Silver , Subsequences Summing to Sevens] 时限 1000MS/Case 内存 128MB/Case ...

  9. 洛谷 P2431 正妹吃月饼 解题报告

    P2431 正妹吃月饼 题目描述 今天是中秋节.\(uim\)带来了一堆大小不同且味道各异的月饼. 这些月饼的质量分别是\(1g\),\(2g\),\(4g\),\(8g\),\(16g\)....后 ...

最新文章

  1. selenium实例:unittest框架+PO开发模式
  2. CentOS7安装Zabbix
  3. php酷狗音乐json,用php来搜索酷狗音乐
  4. 计算机网络之数据链路层:18、数据链路层设备
  5. intellij jsp 中文乱码
  6. CVS update常用技巧
  7. 前端计算机英语单词,解决文件命名,变量命名头皮发麻,单词超多1700个前端专属单词,css常用命名单词【起名字太烦了全背下来内卷吧小伙伴大前端时代来临了】
  8. 基于Mathemtica绘制一元酸滴定碱的滴定曲线(含V--PH曲线方程的推导)
  9. Windows10系统:任务栏中电池图标消失问题的解决方法
  10. 车轱辘通知挪车、车牌识别
  11. SQL Server事物日志
  12. 服务器系统适合家庭电脑用吗,服务器可以用作家用电脑吗?两者有何区别?不怕噪音和耗电就可以...
  13. 【单片机应用】项目一 发光二极管LED控制
  14. 云灾备是更好的“企业保险”,百亿灾备市场迎来阿里云
  15. ionic学习笔记2
  16. 从微信小程序到QQ小程序:云开发CloudBase的一云多端实践
  17. SpaceX载人航天飞船点火升空 送4名宇航员去空间站
  18. 计算机中专专业规划400字,中专计算机专业规划书
  19. 【华人学者风采】蔡登 浙江大学
  20. 一个数异或同一个数两次,结果还是那个数

热门文章

  1. 计算机语言学 自然语言处理程序,利用知网进行(计算机)自然语言处理
  2. linux 6.2 期末考试题,redhat6.2-linux考试试卷(带部分答案)
  3. python的GUI编程和tkinter学习笔记——第一个GUI程序
  4. 二、Web服务器——ServletHTTPRequest笔记
  5. python的普通方法、类方法和静态方法
  6. Spark IDEA 编程环境配置
  7. LeetCode 948. 令牌放置(贪心)
  8. 天池在线编程 2020国庆八天乐 - 4. 生成更大的陆地(BFS)
  9. LeetCode 474. 一和零(01背包动态规划)
  10. 基于奇异值分解(SVD)的图片压缩实践