[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 ...
随机推荐
- MongoDB 备份(mongodump)与恢复(mongorestore)
MongoDB 备份(mongodump)与恢复(mongorestore) 备份:使用mongodump命令导出所有数据库到指定目录 参数说明: --host:MongoDB所在服务器IP. -- ...
- 关于什么是SpringMVC,和SpringMVC基于xml配置、注解配置、纯注解配置
首先我们先要了解一下,什么是SpringMVC? SpringMVC是Spring框架内置的MVC的实现.SpringMVC就是一个Spring内置的MVC子框架,也就是说SpringMVC的相关包都 ...
- 018-并发编程-java.util.concurrent.locks之-ReentrantReadWriteLock可重入读写锁
一.概述 ReentrantLock是一个排他锁,同一时间只允许一个线程访问,而ReentrantReadWriteLock允许多个读线程同时访问,但不允许写线程和读线程.写线程和写线程同时访问.相对 ...
- [Python] Print input and output in table
Print the input and output in a table using prettyTable. from prettytable import PrettyTable import ...
- CSS几个要点补充
css的font-size属性一定要带px单位,font-weight:700[千万不要带单位哦]就等于font-weight:bold加粗 1.如何像淘宝页面一样,随着浏览器的减小而保持内容区大小不 ...
- html5 javascript 事件练习3键盘控制练习
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- Delphi中有关窗口绘制
Invalidate方法通知Windows应该重新绘制表单的整个表面.最重要的是Invalidate不会立即强制执行绘制操作. Windows只是存储请求,并且只会响应它当前程序完全执行后,并且只要系 ...
- C# Remoting例子
4-23 https://www.cnblogs.com/zhengyun_ustc/archive/2006/06/09/remoting_InvalidCredentialException.ht ...
- [openjudge-动态规划]滑雪
题目描述 描述 Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道载一个区 ...
- qemu-kvm内存虚拟化2
2017-04-20 上篇文章对qemu部分的内存虚拟化做了介绍,上篇文章对于要添加的FR,调用了 MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, ...