[poj2201]Cartesian Tree(笛卡尔树)

题目链接:http://poj.org/problem?id=2201

就是给你key和value,建出笛卡尔树。感觉笛卡尔树的建树过程真的优美,按key排序后,每次插入一个点,相当于从根一直向右走的路径上,找到value小于当前点value,并且value最大的点,插入即可,具体看代码吧。

区分笛卡尔式和treap:两者都有key和value,都既满足二叉搜索树的性质,也满足堆的性质,但treap是用value去维护树的平衡,而笛卡尔树的value是我们已知的(好像是吧)。

#include<cstdio>
#include<algorithm>
using namespace std;
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define per(i,x,y) for (int i=(x);i>=(y);i--)
const int N=50010;
struct node{int key,val,id;}a[N];
int n,s[N],l[N],r[N],fa[N];
int read() {int d=0,f=1; char c=getchar(); while (c<‘0‘||c>‘9‘) {if (c==‘-‘) f=-1; c=getchar();} while (c>=‘0‘&&c<=‘9‘) d=(d<<3)+(d<<1)+c-48,c=getchar(); return d*f;}
bool cmp(node a,node b){return a.key<b.key;}
int main()
{
    while (scanf("%d",&n)!=EOF)
    {
        for (int i=1;i<=n;i++) fa[i]=l[i]=r[i]=0;
        for (int i=1;i<=n;i++) a[i].key=read(),a[i].val=read(),a[i].id=i;
        sort(a+1,a+1+n,cmp);
        int k,top=0;
        for (int i=1;i<=n;i++)
        {
            k=top;
            while (k>0&&a[i].val<a[s[k]].val) k--;
            if (k)
            {
                fa[a[i].id]=a[s[k]].id;
                r[a[s[k]].id]=a[i].id;
            }
            if (k<top)
            {
                fa[a[s[k+1]].id]=a[i].id;
                l[a[i].id]=a[s[k+1]].id;
            }
            s[++k]=i;
            top=k;
        }
        fa[a[s[1]].id]=0;
        puts("YES");
        for (int i=1;i<=n;i++) printf("%d %d %d\n",fa[i],l[i],r[i]);
    }
    return 0;
}

时间: 2024-12-14 18:46:32

[poj2201]Cartesian Tree(笛卡尔树)的相关文章

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

笛卡尔树cartesian tree

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

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<<