[TJOI2011]树的序(贪心,笛卡尔树)
[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]树的序(贪心,笛卡尔树)的更多相关文章
- 7.28 NOI模拟赛 H2O 笛卡尔树 并查集 贪心 长链剖分
LINK:H2O 这场比赛打的稀烂 爆蛋. 只会暴力.感觉暴力细节比较多不想写. 其实这道题的难点就在于 采取什么样的策略放海绵猫. 知道了这一点才能确定每次放完海绵猫后的答案. 暴力枚举是不行的.而 ...
- POJ 1785 Binary Search Heap Construction(裸笛卡尔树的构造)
笛卡尔树: 每个节点有2个关键字key.value.从key的角度看,这是一颗二叉搜索树,每个节点的左子树的key都比它小,右子树都比它大:从value的角度看,这是一个堆. 题意:以字符串为关键字k ...
- PTA 笛卡尔树
笛卡尔树 (25 分) 笛卡尔树是一种特殊的二叉树,其结点包含两个关键字K1和K2.首先笛卡尔树是关于K1的二叉搜索树,即结点左子树的所有K1值都比该结点的K1值小,右子树则大.其次所有结点的K2关键 ...
- 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 ...
- [模板] 笛卡尔树 && RMQ
话说我noip之前为什么要学这种东西... 简介 笛卡尔树(Cartesian Tree) 是一种二叉树, 且同时具有以下两种性质: 父亲节点的值大于/小于子节点的值; 中序遍历的结果为原序列. 笛卡 ...
- 平衡树及笛卡尔树讲解(旋转treap,非旋转treap,splay,替罪羊树及可持久化)
在刷了许多道平衡树的题之后,对平衡树有了较为深入的理解,在这里和大家分享一下,希望对大家学习平衡树能有帮助. 平衡树有好多种,比如treap,splay,红黑树,STL中的set.在这里只介绍几种常用 ...
- 笛卡尔树Cartesian Tree
前言 最近做题目,已经不止一次用到笛卡尔树了.这种数据结构极为优秀,但是构造的细节很容易出错.因此写一篇文章做一个总结. 笛卡尔树 Cartesian Tree 引入问题 有N条的长条状的矩形,宽度都 ...
- XJOI 3606 最大子矩形面积/LightOJ 1083 Histogram(单调栈/笛卡尔树)
A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rec ...
- 笛卡尔树 POJ ——1785 Binary Search Heap Construction
相应POJ 题目:点击打开链接 Binary Search Heap Construction Time Limit: 2000MS Memory Limit: 30000K Total Subm ...
随机推荐
- JavaScript高级程序设计部分笔记
1.JavaScript由三个不同的部分组成:ECMAScript(核心).DOM(文档对象模型).BOM(浏览器对象模型). 2.数据的引用类型 Object类型 Array类型 Data类型 Re ...
- sklearn学习3----模型选择和评估(1)训练集和测试集的切分
来自链接:https://blog.csdn.net/zahuopuboss/article/details/54948181 1.sklearn.model_selection.train_test ...
- 基于better-scroll封装一个上拉加载下拉刷新组件
1.起因 上拉加载和下拉刷新在移动端项目中是很常见的需求,遂自己便基于better-scroll封装了一个下拉刷新上拉加载组件. 2.过程 better-scroll是目前比较好用的开源滚动库,提供很 ...
- CentOS安装记录
决定开始复习Linux系统编程,这次我不再折腾Linux下的各种工具,直接使用VS2017进行代码编写与调试. 配置项 值 VM VMware® Workstation 15 Pro OS CentO ...
- BlogEngine.NET架构学习:Extension扩展实现
之前有个系列文章介绍过BlogEngine.NET,其中也有关于插件的介绍:"BlogEngine.Net架构与源代码分析系列part9:开发扩展(上)--Extension与管理上的实现& ...
- js判断 nan null undefined的方法
收集资料如下判断: 1.判断undefined: 复制代码代码如下: <span style="font-size: small;">var tmp = undefin ...
- URAL 1457. Heating Main
space=1&num=1457">1457. Heating Main Time limit: 1.0 second Memory limit: 64 MB Backgrou ...
- debian mysql 定时自己主动备份的脚本
#!/bin/sh LOG=/var/log/mysql-backup.log # mysql db info USER_ROOT=XXXXXX USER_PWD=XXXXXXX # mysql da ...
- poj 2777 Count Color(线段树、状态压缩、位运算)
Count Color Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 38921 Accepted: 11696 Des ...
- web前端project师知识汇总
分类: Web开发应用 一.何为Web前端project师? 前端project师,也叫Web前端开发project师.他是随着web发展.细分出来的行业.Web前端开发proj ...