[sgu P155] Cartesian Tree
155. Cartesian Tree
memory limit per test: 65536 KB
output: standard output
That is, if we denote the left subtree of the node x by L(x), its right subtree by R(x) and its key by kx, for each node x we will have
* if y in L(x) then ky < kx
* if z in R(x) then kz > kx
The binary search tree is called cartesian if its every node x in addition to the main key kx also has an auxiliary key that we will denote by ax, and for these keys the heap condition is satisfied, that is
* if y is the parent of x then ay < ax
Thus a cartesian tree is a binary rooted ordered tree, such that each of its nodes has a pair of two keys (k, a) and three conditions described are satisfied.
Given a set of pairs, construct a cartesian tree out of them, or detect that it is not possible.
If there are several possible trees, output any one.
5 4
2 2
3 9
0 5
1 3
6 6
4 11
2 3 6
0 5 1
1 0 7
5 0 0
2 4 0
1 0 0
3 0 0
cartesian tree,俗称“笛卡尔树”。
笛卡尔树是什么呢?就是一颗类treap树。
即每个节点有两个域值,一个阈值满足二叉排序树性质,另一个域值满足堆性质。
首先说一下,笛卡尔树和treap结构上相似,但实际上,treap的第二个阈值只是用于维护平衡,而笛卡尔树的阈值是真正的值。
这道题目主要是笛卡尔树的建树。
它是O(n)的(核心部分)。
我们先把所有节点按照二叉树值从大到小排序,并假设现在已经建成了一个1~i-1的节点的树。
那么当前节点i按照二叉树值插入一点会插入在最右链的末端。
不过这样,可能会使其父节点的堆值大于他。怎么办?我们相当于做一个左旋操作。
找到第一个堆值比i小的i的祖先u,使i成为u的右儿子,u原来的右子树变为u的左子树,这样就可以满足要求了,并且这样的树一定是存在的。
那么,现在的问题是,怎样找到u?显然,可以二分查找O(nlogn)的复杂度。但这样不是最优的。
最优的就是就是用一个单调栈,记录最右链的节点。由于每一个节点最多访问一次,所以复杂度是O(n)的。
code:
#include<bits/stdc++.h>
using namespace std;
,inf=0x1a1a1a1a;
int n,s[N],top;
struct node {int k,x,i,f,l,r;}a[N];
bool cmp_k(const node &u,const node &v) {return u.k<v.k;}
bool cmp_i(const node &u,const node &v) {return u.i<v.i;}
int main() {
cin>>n,top=;
; i<=n; i++)
scanf("%d%d",&a[i].k,&a[i].x),a[i].i=i;
a[].l=a[].r=a[].i=,a[].k=a[].x=-inf;
sort(a+,a++n,cmp_k);
s[++top]=;
,las=-; i<=n; i++,las=-) {
while (top&&a[s[top]].x>a[i].x) las=s[top],top--;
a[i].f=a[s[top]].i,a[s[top]].r=a[i].i;
if (~las) a[i].l=a[las].i,a[las].f=a[i].i;
s[++top]=i;
}
sort(a+,a++n,cmp_i);
puts("YES");
; i<=n; i++)
printf("%d %d %d\n",a[i].f,a[i].l,a[i].r);
;
}
[sgu P155] Cartesian Tree的更多相关文章
- SGU 155.Cartesian Tree
时间限制:0.25s 空间限制:6M 题意: 给出n(n< 50000)个含双关键字(key,val)的节点,构造一颗树使该树,按key值是一颗二分查找树,按val值是一个小根堆. Soluti ...
- Algorithm: cartesian tree
http://baike.baidu.com/link?url=XUt5fXQ-jtFBM0UdKiGA41_NWFvdFSYwVsy4SVvCRRuEBvNkLfT9TgOtzsXvaOT9nuq_ ...
- 笛卡尔树Cartesian Tree
前言 最近做题目,已经不止一次用到笛卡尔树了.这种数据结构极为优秀,但是构造的细节很容易出错.因此写一篇文章做一个总结. 笛卡尔树 Cartesian Tree 引入问题 有N条的长条状的矩形,宽度都 ...
- PAT-2019年冬季考试-甲级 7-4 Cartesian Tree (30分)(最小堆的中序遍历求层序遍历,递归建树bfs层序)
7-4 Cartesian Tree (30分) A Cartesian tree is a binary tree constructed from a sequence of distinct ...
- Day6 - J - Cartesian Tree POJ - 2201
Let us consider a special type of a binary search tree, called a cartesian tree. Recall that a binar ...
- PAT-1167(Cartesian Tree)根据中序遍历序列重建最小堆
Cartesian Tree PAT-1167 一开始我使用数组进行存储,但是这样可能会导致无法开足够大的数组,因为树如果是链表状的则无法开这么大的数组(虽然结点很少). 正确的解法还是需要建树,使用 ...
- POJ 2201 Cartesian Tree ——笛卡尔树
[题目分析] 构造一颗笛卡尔树,然后输出这棵树即可. 首先进行排序,然后用一个栈维护最右的树的节点信息,插入的时候按照第二关键字去找,找到之后插入,下面的树成为它的左子树即可. 然后插入分三种情况讨论 ...
- OpenJudge Cartesian Tree
[代码] #include <cstdio> #include <cstdlib> #include <cstring> #include <algorith ...
- CF1290E Cartesian Tree
考虑笛卡尔树的意义: 一个点在笛卡尔树中的子树,代表以他为最小/最大值的区间. 所以一个点的子树大小,一定是类似到达序列边界或者被一个比他更大的数隔离. 考虑记录 \(l_i,r_i\) 为第 \(i ...
随机推荐
- Kafka— —副本(均衡负载)
创建一个副本数为3的topic Now create a new topic with a replication factor of three: > bin/kafka-topics.sh ...
- python基础之 面向对象
1.什么是面向对象? 在大学学习c#的时候接触面向对象,知道好像有什么方法,属性,人狗大战啥的.但是都忘记了,也不知道面向对象到底是个啥! 在python中一切都是对象,linux中一切都是文件(突然 ...
- python调用RPC接口
要调用RPC接口,python提供了一个框架grpc,这是google开源的 rpc相关文档: https://grpc.io/docs/tutorials/basic/python.html 需要安 ...
- Linux平台 Oracle 18c RAC安装Part2:GI配置
三.GI(Grid Infrastructure)安装 3.1 解压GI的安装包 3.2 安装配置Xmanager软件 3.3 共享存储LUN的赋权 3.4 使用Xmanager图形化界面配置GI 3 ...
- java之搭建webservice服务端
1.新建工程. 2.配置项目名称和位置. 3.得到的项目结构如下: 4.配置tomcat服务器. (1) (2)新建一个tomcat服务. (3)配置tomcat参数. 5.配置WSDL文件. url ...
- spring-boot 根据环境启动
spring-boot 根据环境启动: java -jar spring-boot--config--SNAPSHOT.jar --spring.profiles.active=prod
- git忽略某些文件的几种方法
不知道为什么我记得我写过这个内容但是又找不到了,只好照着大致记忆写一下以备留存. 1.首先肯定是.gitignore文件 .gitignore文件适合在文件尚未被追踪时加入,将其忽略便可以不上传到远程 ...
- <转>jmeter(十九)HTTP属性管理器
本博客转载自:http://www.cnblogs.com/imyalost/category/846346.html 个人感觉不错,对jmeter讲解非常详细,担心以后找不到了,所以转发出来,留着慢 ...
- 转——git常见使用命令及git原理
0.常用命令1 1.git中brunch的使用和理解(一定理解brunch的指针理解和分叉) 分支创建 Git 是怎么创建新分支的呢? 很简单,它只是为你创建了一个可以移动的新的指针. 比如,创建一个 ...
- Fast Matrix Calculation HDU - 4965
One day, Alice and Bob felt bored again, Bob knows Alice is a girl who loves math and is just learni ...