例①、POJ 2201:
题目:
笛卡尔树:笛卡尔树中的每个节点有两个数据域key,val,对于数据域key,满足二叉搜索树性质,对于数据域val,满足最小堆性质。给出N个节点,1<=N<=50000,每个节点由一对key,val构成,判断能否根据这些节点构建一颗笛卡尔树,如果可以构建则输出构造出的笛卡尔树,否则输出“NO”。
解题思路:首先,根据N个节点,肯定可以构造出一颗笛卡尔树。
//本来是按照val排序,然后建立搜索二叉树,T了
//学了笛卡尔之后才知道,它是按照key排序,然后O(n)建树
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=50100;
const int inf=0x3f3f3f3f;
struct node
{
int l,r,fa;
int val,key;
int id;
bool operator <(const node &b) const
{
return key<b.key;
}
}t[maxn];
int l[maxn],r[maxn],fa[maxn];
void init(void)
{
t[0].l=t[0].r=0;
t[0].val=-inf;
t[0].fa=0;
t[0].id=0;
}
void _insert(int x)
{
int now=x-1;
while(t[now].val>t[x].val) now=t[now].fa;
t[x].l=t[now].r;
t[t[now].r].fa=x;
t[x].fa=now;
t[now].r=x;
}
void dfs(int x)
{
if(!x) return ;
l[t[x].id]=t[t[x].l].id;
r[t[x].id]=t[t[x].r].id;
fa[t[x].id]=t[t[x].fa].id;
dfs(t[x].l);
dfs(t[x].r);
}
int main(void)
{
int n;
while(scanf("%d",&n)!=EOF)
{
init();
for(int i=1;i<=n;i++)
scanf("%d%d",&t[i].key,&t[i].val),t[i].id=i;
sort(t+1,t+n+1);
for(int i=1;i<=n;i++)
_insert(i);
printf("YES\n");
dfs(t[0].r);
for(int i=1;i<=n;i++)
printf("%d %d %d\n",fa[i],l[i],r[i]);
}
return 0;
}
例②、P5854 【模板】笛卡尔树
题目描述
给定一个 1∼n 的排列 p,构建其笛卡尔树。
即构建一棵二叉树,满足:
每个节点的编号满足二叉搜索树的性质。
节点 i 的权值为 pi ,每个节点的权值满足小根堆的性质。
输入格式
第一行一个整数 n。
第二行一个排列 p1…n 。
输出格式
设 li,ri 分别表示节点 i 的左右儿子的编号(若不存在则为 0)。
一行两个整数,分别表示 xor_sum of i * (li+1) , xor_sum of i * (ri+1)
输入输出样例
输入 #1 复制
5
4 1 3 2 5
输出 #1 复制
19 21
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
char buffer[100001],*S,*T;
inline char Get_Char()
{
if (S==T)
{
T=(S=buffer)+fread(buffer,1,100001,stdin);
if (S==T) return EOF;
}
return *S++;
}
inline int read()
{
char c;int re=0;
for(c=Get_Char();c<'0'||c>'9';c=Get_Char());
while(c>='0'&&c<='9') re=(re<<1)+(re<<3)+(c-'0'),c=Get_Char();
return re;
}
const int maxn=10000100;
const int inf=0x3f3f3f3f;
struct node
{
int l,r,fa;
int val;
}t[maxn];
void init(void)
{
t[0].l=t[0].r=0;
t[0].val=-inf;
t[0].fa=0;
}
void _insert(int x)
{
int now=x-1;
while(t[now].val>t[x].val) now=t[now].fa;
t[x].l=t[now].r;
t[t[now].r].fa=x;
t[x].fa=now;
t[now].r=x;
}
int main(void)
{
int n;
init();
n=read();
for(int i=1;i<=n;i++)
t[i].val=read(),_insert(i);
ll ansl=0,ansr=0;
for(ll i=1;i<=n;i++)
ansl^=i*(t[i].l+1),ansr^=i*(t[i].r+1);
printf("%lld %lld\n",ansl,ansr);
return 0;
}