1. 程式人生 > >LCA in a Binary Tree PAT甲級 - 1151

LCA in a Binary Tree PAT甲級 - 1151

https://pintia.cn/problem-sets/994805342720868352/problems/1038430130011897856

給定前序中序 還原二叉樹

用單調棧掃一遍前序 對於一個點 他的父節點的前序肯定小於它 如過棧頂節點的左子樹的中序區間包含當前節點 則當前節點為棧頂節點的左孩子 否則是右孩子 或者沒有父子關係則pop棧頂

這題有毒啊 給的前序中序不一定是1-n的全排列

 

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e4+10;

struct node
{
    int id,l,r,m,flag;
};

map <int,int> mp1,mp2;
stack <node> stk;
int ch[maxn][2],fa[maxn];
int pre[maxn],mid[maxn],pos[maxn],lef[maxn],rgt[maxn],deep[maxn];
int n,q,num;

int getlca(int u,int v)
{
    if(deep[u]<deep[v]) swap(u,v);
    while(!(lef[u]<=pos[v]&&pos[v]<=rgt[u])) u=fa[u];
    return u;
}

int main()
{
    node cur,tmp;
    int i,u,v,uu,vv,lca;
    scanf("%d%d",&q,&n);
    for(i=1;i<=n;i++){
        scanf("%d",&mid[i]);
        num++;
        mp1[mid[i]]=num,mp2[num]=mid[i];
        pos[num]=i;
    }
    for(i=1;i<=n;i++){
        scanf("%d",&pre[i]);
        pre[i]=mp1[pre[i]];
    }
    tmp.id=pre[1],tmp.l=1,tmp.r=n,tmp.m=pos[pre[1]],tmp.flag=0;
    stk.push(tmp);
    lef[pre[1]]=1,rgt[pre[1]]=n;
    for(i=2;i<=n;i++){
        while(!stk.empty()){
            cur=stk.top();
            stk.pop();
            if(cur.flag==0){
                cur.flag=1;
                if(cur.l<=pos[pre[i]]&&pos[pre[i]]<=cur.m-1){
                    ch[cur.id][0]=pre[i],fa[pre[i]]=cur.id;
                    stk.push(cur);
                    tmp.id=pre[i],tmp.l=cur.l,tmp.r=cur.m-1,tmp.m=pos[pre[i]],tmp.flag=0;
                    stk.push(tmp);
                    lef[pre[i]]=tmp.l,rgt[pre[i]]=tmp.r,deep[pre[i]]=deep[cur.id]+1;
                    break;
                }
            }
            if(cur.flag==1){
                if(cur.m+1<=pos[pre[i]]&&pos[pre[i]]<=cur.r){
                    ch[cur.id][1]=pre[i],fa[pre[i]]=cur.id;
                    tmp.id=pre[i],tmp.l=cur.m+1,tmp.r=cur.r,tmp.m=pos[pre[i]],tmp.flag=0;
                    stk.push(tmp);
                    lef[pre[i]]=tmp.l,rgt[pre[i]]=tmp.r,deep[pre[i]]=deep[cur.id]+1;
                    break;
                }
            }
        }
    }
    while(q--){
        scanf("%d%d",&uu,&vv);
        u=mp1[uu],v=mp1[vv];
        if(!u&&!v) printf("ERROR: %d and %d are not found.\n",uu,vv);
        else if(!u&&v) printf("ERROR: %d is not found.\n",uu);
        else if(u&&!v) printf("ERROR: %d is not found.\n",vv);
        else{
            lca=getlca(u,v);
            if(lca==u) printf("%d is an ancestor of %d.\n",uu,vv);
            else if(lca==v) printf("%d is an ancestor of %d.\n",vv,uu);
            else printf("LCA of %d and %d is %d.\n",uu,vv,mp2[lca]);
        }
    }
    return 0;
}