如题,我的思路是可以根据先序遍历找到每个点的dfn,并根据中序遍历找到每个点的子树是哪两部分。由于在中序遍历中,一棵子树呈现为一个区间,所以这个子树的根就是这个区间dfn最小的那个点。
在本地和在AtCoder上开了一样的栈空间,本地没有问题,交上去RE了,为什么呢?
#include<cstdio>
using namespace std;
const int MAXN=2e5+10;
int lson[MAXN],rson[MAXN];
int dfn[MAXN],dfn_buc[MAXN];//dfn[i]表示第i个点的dfn,dfn_buc[i]表示dfn=i的点
int n;
int a[MAXN],point_buc[MAXN];//a表示中序遍历序列,point_buc[i]表示点i在中序遍历中的位置
int slove(int l,int r,int mindfn){
if(l>r){
return 0;
}
if(l==r){
lson[a[l]]=0;
rson[a[r]]=0;
return a[l];
}
int po=dfn_buc[mindfn];
int p=point_buc[po];
lson[po]=slove(l,p-1,mindfn+1);
rson[po]=slove(p+1,r,mindfn+p-l+1);
return po;
}
int main(){
// freopen("ABC255F.in","r",stdin);
// freopen("ABC255F.out","w",stdout);
scanf("%d",&n);
for(int i=1,t;i<=n;++i){
scanf("%d",&t);
dfn[t]=i;
dfn_buc[i]=t;
lson[i]=1919810;
}
if(dfn[1]!=1){
putchar('-');putchar('1');
return 0;
}
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
point_buc[a[i]]=i;
}
slove(1,n,1);
for(int i=1;i<=n;++i){
printf("%d %d\n",lson[i],rson[i]);
}
return 0;
}