https://www.luogu.com.cn/problem/P1377
二叉搜索树的性质:1.父节点一定比子节点早出现。2.左子树的值<=根<=右子树的值
笛卡尔树的性质:1.父节点的值一定比子节点小 2.左子树出现早于根节点早于右子树
那么如果我们把二叉搜索树的值换成下标,下标换成值,那么就是一笛卡尔树了。
这题要求字典序最小,显然就是求二叉搜索树的前序遍历中的权值顺序,那么也就是求笛卡尔树中的下标顺序。
#include<bits/stdc++.h>
using namespace std;
const int maxl=1e5+10;
int n;
int a[maxl];
struct node
{
int k,val,fa,ls,rs;
}tr[maxl];
inline void prework()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
tr[a[i]]=node{a[i],i,0,0,0};
}
}
inline int build(int n)
{
int k;
for(int i=1;i<=n;i++)
{
k=i-1;
while(tr[k].val>tr[i].val)
k=tr[k].fa;
tr[i].fa=k;
tr[i].ls=tr[k].rs;
tr[tr[k].rs].fa=i;
tr[k].rs=i;
}
return tr[0].rs;
}
inline void dfs(int u)
{
printf("%d ",u);
if(tr[u].ls)
dfs(tr[u].ls);
if(tr[u].rs)
dfs(tr[u].rs);
}
inline void mainwork()
{
tr[0]={0,0,0,0,0};
int rt=build(n);
dfs(rt);
}
int main()
{
prework();
mainwork();
//print();
return 0;
}