笛卡尔树cartesian tree

笛卡尔树cartesian tree

笛卡尔树是一种特定的二叉树数据结构,可由数列构造,在范围最值查询、范围top k查询(range top k queries)等问题上有广泛应用。它具有堆的有序性,中序遍历可以输出原数列。笛卡尔树结构由Vuillmin(1980)[1]在解决范围搜索的几何数据结构问题时提出。从数列中构造一棵笛卡尔树可以线性时间完成,需要采用基于栈的算法来找到在该数列中的所有最近小数。

定义

无相同元素的数列构造出的笛卡尔树具有下列性质:

  1. 结点一一对应于数列元素。即数列中的每个元素都对应于树中某个唯一结点,树结点也对应于数列中的某个唯一元素
  2. 中序遍历(in-order traverse)笛卡尔树即可得到原数列。即任意树结点的左子树结点所对应的数列元素下标比该结点所对应元素的下标小,右子树结点所对应数列元素下标比该结点所对应元素下标大。
  3. 树结构存在堆序性质,即任意树结点所对应数值大/小于其左、右子树内任意结点对应数值

根据堆序性质,笛卡尔树根结点为数列中的最大/小值,树本身也可以通过这一性质递归地定义:根结点为序列的最大/小值,左、右子树则对应于左右两个子序列,其结点同样为两个子序列的最大/小值。因此,上述三条性质唯一地定义了笛卡尔树。若数列中存在重复值,则可用其它排序原则为数列中相同元素排定序列,例如以下标较小的数为较小,便能为含重复值的数列构造笛卡尔树。

a binary search tree is a rooted ordered binary tree, such that for its every node x the following condition is satisfied: each node in its left subtree has the key less then the key of
x, and each node in its right subtree has the key greater then the key of x.

That is, if we denote left subtree of the node x by L(x), its right subtree by R(x) and its key by kx then for each node x we have

  • if y ∈ L(x) then ky < kx
  • if z ∈ 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.

笛卡尔树是一棵二叉树,树的每个节点有两个值,一个为key,一个为value。光看key的话,笛卡尔树是一棵二叉搜索树,每个节点的左子树的key都比它小,右子树都比它大;光看value的话,笛卡尔树有点类似堆,根节点的value是最小(或者最大)的,每个节点的value都比它的子树要大。

http://poj.org/problem?id=2201

from:

http://blog.csdn.net/pipisorry/article/details/39033269

ref:

笛卡尔树 http://zh.wikipedia.org/zh-cn/%E7%AC%9B%E5%8D%A1%E5%B0%94%E6%A0%91

时间: 2024-12-21 06:17:12

笛卡尔树cartesian tree的相关文章

[poj2201]Cartesian Tree(笛卡尔树)

题目链接:http://poj.org/problem?id=2201 就是给你key和value,建出笛卡尔树.感觉笛卡尔树的建树过程真的优美,按key排序后,每次插入一个点,相当于从根一直向右走的路径上,找到value小于当前点value,并且value最大的点,插入即可,具体看代码吧. 区分笛卡尔式和treap:两者都有key和value,都既满足二叉搜索树的性质,也满足堆的性质,但treap是用value去维护树的平衡,而笛卡尔树的value是我们已知的(好像是吧). #include<

POJ-2201-Cartesian Tree(笛卡尔树)

Description Let us consider a special type of a binary search tree, called a cartesian tree. Recall that a binary search tree is a rooted ordered binary tree, such that for its every node x the following condition is satisfied: each node in its left

POJ-1785-Binary Search Heap Construction(笛卡尔树)

Description Read the statement of problem G for the definitions concerning trees. In the following we define the basic terminology of heaps. A heap is a tree whose internal nodes have each assigned a priority (a number) such that the priority of each

NOIP2011pj表达式的值[树形DP 笛卡尔树]

题目描述 对于1 位二进制变量定义两种运算: 运算的优先级是: 先计算括号内的,再计算括号外的. “× ”运算优先于“⊕”运算,即计算表达式时,先计算× 运算,再计算⊕运算.例如:计算表达式A⊕B × C时,先计算 B × C,其结果再与 A 做⊕运算. 现给定一个未完成的表达式,例如+(*_),请你在横线处填入数字0 或者1 ,请问有多少种填法可以使得表达式的值为0 . 输入输出格式 输入格式: 输入文件名为exp.in ,共 2 行. 第1 行为一个整数 L,表示给定的表达式中除去横线外的运

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

相应POJ 题目:点击打开链接 Binary Search Heap Construction Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 9075   Accepted: 2566 Description Read the statement of problem G for the definitions concerning trees. In the following we define the basic

[hdu1506 Largest Rectangle in a Histogram]笛卡尔树

题意:http://acm.hdu.edu.cn/showproblem.php?pid=1506 如图,求最大的矩形面积 思路: 笛卡尔树:笛卡尔树是一棵二叉树,树的每个节点有两个值,一个为key,一个为value.光看key的话,笛卡尔树是一棵二叉搜索树,每个节点的左子树的key都比它小,右子树都比它大:光看value的话,笛卡尔树有点类似堆,根节点的value是最小(或者最大)的,每个节点的value都比它的子树要小(或者大). 笛卡尔树的构造算法:从右链插入,同时维护右链的递增或递减序列

HDU - 1506 Largest Rectangle in a Histogram (单调栈/笛卡尔树)

题意:求一个直方图中最大矩形的面积. 很经典的一道问题了吧,可以用单调栈分别求出每个柱子左右两边第一个比它低的柱子(也就相当于求出了和它相连的最后一个比它高的柱子),确定每个柱子的左右边界,每个柱子的高度乘上左右边界的宽度求最大值就行了. 也可以用笛卡尔树上dp的方法搞一搞,即用每个结点权值和所在子树的大小分别表示高度和宽度.(建笛卡尔树的过程也用到了单调栈,作用是维护右链) 单调栈做法: 1 #include<bits/stdc++.h> 2 using namespace std; 3 t

笛卡尔树及克鲁斯卡尔重构树

笛卡尔树 好东西, 可以用于最大(小)值分治, 在\(O(n)\)的时间复杂度内建出一个节点为区间最大值的树, 每次分治时走小区间可以保证\(O(nlog_n)\)的复杂度 建树时维护极右链, 他的中序遍历即原序列 代码 #include<bits/stdc++.h> using namespace std; const int N=1e5+10; int n,v[N],fa[N],ls[N],rs[N]; int s[N],top; void Tree() { for(int i = 1;

hdu 5412 CRB and Queries(线段树套笛卡尔树 - 动态区间第k大)

题目链接:hdu 5412 CRB and Queries 首先对所有出现过的值排序,建立线段树,每个线段树的节点是一棵笛卡尔树,笛卡尔树记录区间下标值. #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; #define lson(x) (x<<1) #define rson(x) ((x<<