笛卡尔树学习笔记
笛卡尔树
下文的资料多摘自OI Wiki
性质#
笛卡尔树是一种二叉树,每一个节点都由一个键值二元组
例如 OI Wiki 上的这张图:
上面的这棵树是按每一个点内的值为键值
像上面这棵树一样键值
谈到笛卡尔树,很容易让人想到一种家喻户晓的结构—— Treap。没错,Treap 是笛卡尔树的一种,只不过
构建#
过程#
我们考虑将元素的键值
显然每个数最多进出右链一次(或者说每个点在右链中存在的是一段连续的时间)。这个过程我们可以用栈维护,栈中维护当前笛卡尔树的右链上的结点。一个点不在右链上了就把它弹掉。这样每个点最多进出一次,复杂度
实现#
for (int i = 1; i <= n; i++) {
int k = top;
while (k > 0 && h[stk[k]] > h[i]) k--;
if (k) rs[stk[k]] = i; // rs代表笛卡尔树每个节点的右儿子
if (k < top) ls[i] = stk[k + 1]; // ls代表笛卡尔树每个节点的左儿子
stk[++k] = i;
top = k;
}
P5854 【模板】笛卡尔树#
这道题最后的输出没有什么难的,主要是建树。
我们可以用一个单调栈来维护一下,我们按照编号顺序插入,那么我们当前点肯定是往最右端插入,所以我们如果发现当前点是大于栈顶元素的话,我们就可以直接将其设为当前堆顶元素的右子树;如果不是的话,我们就要将栈内比其大的元素都弹出,然后将其设为最后一个小于他的点的右子树,然后将他设为第一个大于他的点的左子树,这样就能完美维护堆的性质了。
#include<bits/stdc++.h>
#define int long long
#define N 10000100
using namespace std;
int n,a[N],stk[N],ls[N],rs[N];
int l,r,pos,top;
inline int read(){int x=0,f=1;char ch=getchar();while(!isdigit(ch)){f=ch!='-';ch=getchar();}while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return f?x:-x;}
signed main()
{
n=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
pos=top;
while(pos&&a[stk[pos]]>a[i])pos--;
if(pos)rs[stk[pos]]=i;
if(pos<top)ls[i]=stk[pos+1];
stk[top=++pos]=i;
}
for(int i=1;i<=n;i++)
l^=1ll*i*(ls[i]+1),r^=1ll*i*(rs[i]+1);
cout<<l<<" "<<r<<endl;
return 0;
}
P1377 [TJOI2011] 树的序#
给你一串序列,以序列的值为下标,当前的序号为键值建笛卡尔树,最后先序遍历一遍输出即可。
#include<bits/stdc++.h>
#define int long long
#define N 100010
using namespace std;
int n,a[N],stk[N],ls[N],rs[N];
inline void dfs(int x){if(x)cout<<x<<" ",dfs(ls[x]),dfs(rs[x]);}
signed main()
{
int x,pos=0,top=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x;
a[x]=i;
}
for(int i=1;i<=n;i++)
{
pos=top;
while(pos&&a[stk[pos]]>a[i])pos--;
if(pos)rs[stk[pos]]=i;
if(pos<top)ls[i]=stk[pos+1];
stk[top=++pos]=i;
}
dfs(stk[1]);
return 0;
}
作者: 北烛青澜
出处:https://www.cnblogs.com/Multitree/p/17066653.html
本站使用「CC BY 4.0」创作共享协议,转载请在文章明显位置注明作者及出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理