首页 > 其他分享 >笛卡尔树

笛卡尔树

时间:2023-05-09 15:22:55浏览次数:46  
标签:ch val 笛卡尔 key 节点 define

性质

  1. 其节点具有 \(2\) 个权值,分别是 \((key,val)\),以 \(key\) 看,其为一颗二叉搜索树,以 \(val\) 看,其为一个堆(定义)。
  • 二叉搜索树:左子树如果不空,则其权值一定小于根节点;右子树如果不空,则其权值一定大于根节点。

  • 堆:完全二叉树,每个节点的值大于等于(或小于等于)其子树中的每个节点。

  1. 如果笛卡尔树的 \((key,val)\) 键值确定,且 \(key,val\) 都分别互不相同,那么这个笛卡尔树的结构是唯一的。

  2. 特殊的笛卡尔树:\(key\) 为数组下标,此时的笛卡尔树任意一个子树下标都是连续区间。

实现思路

将数组按照 \(key\) 排序,然后按序插入,显然我们每次只能将它插在最右边的末端。

对于每一个元素,我们从下往上比较最右边链上的所有点,如果找到一点 \(p\),满足 \(p_w<u_w\) (大根堆就反过来),那么将 \(u\) 变为 \(p\) 的右儿子,而原右子树变为 \(u\) 的左子树。对于这条链,考虑用栈维护(每个点只会进栈出栈一次)。

时间复杂度 \(O(n)\)。

如下图:

(图片来自 \(\text{oi-wiki}\))

板子&习题

洛谷 P5854 【模板】笛卡尔树

#include<bits/stdc++.h>
#define int long long
#define debug puts("Shiina_Mashiro_kawaii")
#define ok puts("Yes")
#define no puts("No")
#define inf 1e9
using namespace std;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
const int maxn=1e7+5;
int n;
int ansl,ansr;
int a[maxn];
int tree[maxn],l[maxn],r[maxn];
void build_tree(){
	int top=0,pos=0;
	for(register int i=1;i<=n;++i){
		pos=top;
		while(a[i]<a[tree[pos]]){
			if(pos!=0) pos--;
		}
		if(pos<top) l[i]=tree[pos+1];
        if(pos!=0) r[tree[pos]]=i;
        pos++;top=pos;
        tree[top]=i;
	}
}
inline void init(){
	n=read();
	for(register int i=1;i<=n;++i) a[i]=read();
	build_tree();
}
signed main(){
	init();
	for(register int i=1;i<=n;++i){
		ansl^=(l[i]+1)*i;ansr^=(r[i]+1)*i;
	}
    printf("%lld %lld",ansl,ansr);
}

标签:ch,val,笛卡尔,key,节点,define
From: https://www.cnblogs.com/yizhixiaoyun/p/17385018.html

相关文章

  • @黎耀天 发扬 笛卡尔, @物空必能 发扬 牛顿, 无敌了 。
    @黎耀天发扬笛卡尔, @物空必能发扬牛顿,  @joywee2007 发扬爱因斯坦和老子,  无敌了 。 这篇文章的灵感来自 昨前天 看到 @物空必能在牛顿吧发的 《物质的弹性与屈服强度——力学就应当探究力的问题》    https://tieba.baidu.com/p/83932......
  • C++ 树进阶系列之笛卡尔树的两面性
    1.前言笛卡尔树是一种特殊的二叉树数据结构,融合了二叉堆和二叉搜索树两大特性。笛卡尔树可以把数列(组)对象映射成二叉树,便于使用笛卡尔树结构的逻辑求解数列的区间最值或......
  • 笛卡尔树~cartesian-tree
    笛卡尔树简介笛卡尔树是一种平衡树,它的结构和treap相同,但是由于它能在O(n)时间构造,同时具有一些很有意思的性质。构造笛卡尔树的节点由键值对\((k,w)\)组成。其中键......
  • 笛卡尔树
    笛卡尔树总述笛卡尔树是一种二叉树,每一个结点由一个键值二元组\((k,w)\)构成。要求\(k\)满足二叉搜索树的性质,而\(w\)满足堆的性质,如果笛卡尔树的\(k,w\)键值确......
  • 动态笛卡尔树
    这里讲的动态笛卡尔树的问题指的是你要对一个序列单点加值并维护笛卡尔树的形态信息。由于具有严格偏序关系的数列对应的笛卡尔树唯一,我们只需要像维护Treap一样单点上......
  • 【YBT2023寒假Day12 B】仰望星空(DP)(线段树)(笛卡尔树)
    仰望星空题目链接:YBT2023寒假Day12B题目大意有一个n*n的网格,第i列下面的ai个点都是障碍。然后又一些不是障碍的地方有特殊点,删掉它有费用。要你用最小费用使得......
  • 为笛卡尔积运算而生的Reduce(Excel函数集团)
    我要是没记错,Reduce这词是减少的意思,可是当他作为Excel函数出现时,我真没看出哪里Reduce了……好吧,其实可以换种理解,缩减了嵌套(帮助里写的是“将数组缩减为累计值)。来来来......
  • left join(左连接)、right join(右连接)、full join(全连接)、inner join(内连接)、cr
    (1)leftjoin(左连接)在两张表进行连接查询时,会返回左表所有的行数据,右表中返回只返回和左表匹配的数据,没有的显示为Null。(2)rightjoin(右连接)在两张表进行连接查询时,会返......
  • 笛卡尔树学习笔记
    笛卡尔树下文的资料多摘自OIWiki性质笛卡尔树是一种二叉树,每一个节点都由一个键值二元组\((k,w)\)构成。要求\(k\)满足二叉搜索树的性质,而\(w\)满足堆的性质。如......
  • 笛卡尔树
    这篇文章有一部分是2021年写的,当时完全没有理解笛卡尔树的本质。笛卡尔树就是最值分治的搜索树。所以最容易的构建笛卡尔树的方式为:intget(intl,intr){ //返回[l......