[TJOI2011]树的序

题目描述

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

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

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1: 复制

4

1 3 4 2

输出样例#1: 复制

1 3 2 4

说明

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

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

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

题解

先看出题目是直接建树然后贪心输出中序遍历。

然后交上去。发现如果树是链的话就被卡成\(O(n^2)\)。

怎么办呢?点开题解

发现题解多是笛卡尔树。

笛卡尔树是什么鬼东西(蒟蒻表示不会啊)

那就去学(抄题解)吧。

笛卡尔树类似于\(treap\)。

维护两个值,一个为\(key\)值即点权值,另一个在本题维护为\(id\),即出现顺序。

笛卡尔树是利用单调栈的特性建树的。

按样例的\(key\)值从小到大排序后。

\(id\)值为\(1,4,2,3.\)

我们先把\(1\)放进树。

然后让\(1\)点连右儿子\(key\)值为\(2\),\(id\)为\(4\)的点。

然后\(key\)值为\(3\)时,前面的\(2\)的\(id\)比3的\(id\)大。

即按中序遍历,\(3\)的左儿子是\(2\)。

于是就断开\(1\)连向\(2\)的边,然后连向\(3\),并让\(3\)向\(2\)连一条边作为左儿子。

建树的性质就是这样的。

\(O(n)\)建树。

代码

先上\(O(n^2)\)写法

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=1000001;
struct node{
int ch[2],vi;
}t[N<<1];
int ch[N],n,cnt=1,ans[N],tot;
int read(){
int x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*w;
} void build(int x){
int root=1;
while(t[root].ch[t[root].vi<ch[x]])root=t[root].ch[t[root].vi<ch[x]];
t[root].ch[t[root].vi<ch[x]]=++cnt;
t[cnt].vi=ch[x];
} void dfs(int x){
ans[++tot]=t[x].vi;
if(t[x].ch[0])dfs(t[x].ch[0]);
if(t[x].ch[1])dfs(t[x].ch[1]);
} int main(){
n=read();
for(int i=1;i<=n;i++)ch[i]=read();
t[1].vi=ch[1];
for(int i=2;i<=n;i++)build(i);
dfs(1);
for(int i=1;i<=n;i++)printf("%d ",ans[i]);
return 0;
}

AC代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1000010;
struct node{
int vi,ch[2],fa,id;
}ch[N],t[N];
int n,tot,line[N];
int read(){
int x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*w;
} bool cmp(node a,node b){
return a.vi<b.vi;
} void add(int fa,int now,int f){
t[fa].ch[f]=now;
} void dfs(int x){
if(!x)return;
printf("%d ",t[x].vi);
dfs(t[x].ch[0]);dfs(t[x].ch[1]);
} int main(){
n=read();
for(int i=1;i<=n;i++){
ch[i].vi=read();ch[i].id=i;
}
sort(ch+1,ch+n+1,cmp);
for(int i=1;i<=n;i++){
int last=0;
while(tot&&t[line[tot]].id>ch[i].id)
last=tot--;
t[i].id=ch[i].id;t[i].vi=ch[i].vi;
add(line[tot],i,1);add(i,line[last],0);
line[++tot]=i;
}
dfs(t[0].ch[1]);
return 0;
}

[TJOI2011]树的序(贪心,笛卡尔树)的更多相关文章

  1. 7.28 NOI模拟赛 H2O 笛卡尔树 并查集 贪心 长链剖分

    LINK:H2O 这场比赛打的稀烂 爆蛋. 只会暴力.感觉暴力细节比较多不想写. 其实这道题的难点就在于 采取什么样的策略放海绵猫. 知道了这一点才能确定每次放完海绵猫后的答案. 暴力枚举是不行的.而 ...

  2. POJ 1785 Binary Search Heap Construction(裸笛卡尔树的构造)

    笛卡尔树: 每个节点有2个关键字key.value.从key的角度看,这是一颗二叉搜索树,每个节点的左子树的key都比它小,右子树都比它大:从value的角度看,这是一个堆. 题意:以字符串为关键字k ...

  3. PTA 笛卡尔树

    笛卡尔树 (25 分) 笛卡尔树是一种特殊的二叉树,其结点包含两个关键字K1和K2.首先笛卡尔树是关于K1的二叉搜索树,即结点左子树的所有K1值都比该结点的K1值小,右子树则大.其次所有结点的K2关键 ...

  4. Codeforces Round #114 (Div. 1) D. Wizards and Roads 笛卡尔树+树贪心+阅读题

    D. Wizards and Roads 题目连接: http://www.codeforces.com/contest/167/problem/D Description In some count ...

  5. [模板] 笛卡尔树 && RMQ

    话说我noip之前为什么要学这种东西... 简介 笛卡尔树(Cartesian Tree) 是一种二叉树, 且同时具有以下两种性质: 父亲节点的值大于/小于子节点的值; 中序遍历的结果为原序列. 笛卡 ...

  6. 平衡树及笛卡尔树讲解(旋转treap,非旋转treap,splay,替罪羊树及可持久化)

    在刷了许多道平衡树的题之后,对平衡树有了较为深入的理解,在这里和大家分享一下,希望对大家学习平衡树能有帮助. 平衡树有好多种,比如treap,splay,红黑树,STL中的set.在这里只介绍几种常用 ...

  7. 笛卡尔树Cartesian Tree

    前言 最近做题目,已经不止一次用到笛卡尔树了.这种数据结构极为优秀,但是构造的细节很容易出错.因此写一篇文章做一个总结. 笛卡尔树 Cartesian Tree 引入问题 有N条的长条状的矩形,宽度都 ...

  8. XJOI 3606 最大子矩形面积/LightOJ 1083 Histogram(单调栈/笛卡尔树)

    A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rec ...

  9. 笛卡尔树 POJ ——1785 Binary Search Heap Construction

    相应POJ 题目:点击打开链接 Binary Search Heap Construction Time Limit: 2000MS   Memory Limit: 30000K Total Subm ...

随机推荐

  1. django patch

    import datetime import pytz from django.apps import AppConfig from django.db.models.fields import Da ...

  2. Lua 中的 RSA 加解密实现

    记得之前,部门某款游戏陆陆续续收到一些玩家反馈,抱怨在登录游戏时会等待很久.初步排查后基本断定可能是此游戏的登录服务器程序某块代码有问题,于是即安排了服务器同事作排查分析但一直无果. 之后我时间有了空 ...

  3. tinymce原装插件源码分析(七)-使能css、script

    在tinymce中使用css个script tinymce的编辑器中css和script默认是不起作用的.(编辑器主要面向写文章使用,考虑到xss攻击,默认是不启用的) 需要修改tinymce.js中 ...

  4. vue自定义tap指令

    1.Vue指令 Vue提供自定义实现指令的功能, 和组件类似,可以是全局指令和局部指令,详细可以参见vue官网自定义指令一节(https://cn.vuejs.org/v2/guide/custom- ...

  5. 【HiJ1m】在NOIP2017前写过的有用的东西汇总

    http://www.cnblogs.com/Elfish/p/7544623.html 高级树状数组 http://www.cnblogs.com/Elfish/p/7554420.html BST ...

  6. Mysql字段合并

    现有数据 合并字段显示:利用GROUP_CONCAT(course,":","score") 严格区分大小写!GROUP_CONCAT 复制代码 SELECT ...

  7. 亚马逊AWS学习——多网络接口下配置EC2实例连接公网的一个“bug”

    转载请注明出处:http://blog.csdn.net/dongdong9223/article/details/47667627 本文出自[我是干勾鱼的博客] 之前在<亚马逊AWS学习--E ...

  8. 弹性ScrollView,和下啦刷新的效果相似 实现下拉弹回和上拉弹回

    今天做了一个弹性ScrollView,和下啦刷新的效果类似,我想这个非常多需求都用的这样的效果 事实上这是一个自己定义的scrollView,上代码.这是我写在一个公共的组件包里的 package c ...

  9. vijos-1382 寻找主人

    题意: 给出两个同样长度的数字串: 求两个串是否本质同样.同样则输出最小表示. 长度L似乎给的不正确,大概是2000000左右吧: 题解: 最小表示法裸题.证明正确性啥的详见论文吧: 这东西大体的思路 ...

  10. Linux就该这么学 20181007第十章Apache)

    参考链接https://www.linuxprobe.com/ /etc/httpd/conf/httpd.conf 主配置文件 SElinux域 ---服务功能的限制 SElinux安全上下文 -- ...