笛卡尔树

笛卡尔树

前置知识:单调栈
基础知识

这里做点总结
笛卡尔树有两条性质

  • 二叉搜索树
  • 小根堆

定理:编号权值互不相同的笛卡尔树构造是唯一的

二叉搜索树满足
左儿子权值小于父节点,右儿子权值大于父节点

小根堆满足权值小于左右节点
(两个权值不能混为一谈)

因为笛卡尔树结点是由二元组(x,y)组成
x为二叉搜索树满足的权值,y为小根堆满足的权值

我们维护一个右链,即从根往右儿子走的链

插入时,我们从右链末端走,如果值小于末端的值,那就往上走,找到一个结点比插入值还小
如果有右子树,就把这个结点的右子树变为插入值的左子树,插入值变为这个结点的右二子
否则,直接变为右子树
如果找不到小于这个值的结点
则直接作为根

上述操作并未破坏笛卡尔树的性质,自我思考reason

这道题是维护小根堆
下面一道题是维护二叉树性质

#include<cstdio>
#include<cstring>
#include<iostream>

using namespace std;
const int maxn=1e7+10;
int st[maxn],top=0;//st数组维护右链(从根往右儿子走),因为笛卡尔树也是一个二叉搜索树,所以右儿子一直比父节点大
int l[maxn],r[maxn];
int a[maxn];
long long ans1=0,ans2=0; 
int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch>'9' || ch<'0'){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*f;
}int n;
int main(){
	n=read();
	for(int i=1;i<=n;++i){
		a[i]=read();
		int pos=top;
		while(pos && a[st[pos]]>a[i]) --pos;//维护右链
		if(pos) r[st[pos]]=i;//代替节点右二子
		if(pos<top) l[i]=st[pos+1];//原本有右儿子换为插入节点的左儿子
		st[top=++pos]=i;//入栈,保证单调递增
	}
	for(int i=1;i<=n;++i){
		ans1^=(long long )i*(l[i]+1);
		ans2^=(long long )i*(r[i]+1); 
	}cout<<ans1<<" "<<ans2<<endl;
	return 0;
}

[TJOI2011]树的序

首先我们给定了二叉查找树的权值,但是如果就只是单纯的二叉查找树极有可能退化成链

但是会发现插入的顺序满足儿子节点比父节点晚(大),那么就满足小根堆,就可以构造笛卡尔树

先序遍历即可

定义一个结构体val为满足二叉树,id满足堆

struct node{
  int val,id;
}a[]
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>

using namespace std;
const int maxn=1e5+10;

int st[maxn],top=0;
int n;
int l[maxn],r[maxn];
struct node{
	int val,id;
}a[maxn];
bool cmp(node a,node b){
	return a.val<b.val;
}
void dfs(int root){
	if(!root)return ;
	cout<<a[root].val<<" ";
	dfs(l[root]);
	dfs(r[root]);
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n;
	for(int i=1;i<=n;++i)
		cin>>a[i].val,a[i].id=i;
	sort(a+1,a+1+n,cmp); //按权值排序
	for(int i=1;i<=n;++i){
		int pos=top;
		while(pos && a[st[pos]].id>a[i].id) --pos;
		if(pos) r[st[pos]]=i;
		if(pos<top) l[i]=st[pos+1];
		st[top=++pos]=i;
	}
	dfs(st[1]);
	return 0;
} 

如果觉得讲的不顾透彻点这里

posted @ 2021-08-21 11:36  归游  阅读(90)  评论(0编辑  收藏  举报