1151 LCA in a Binary Tree (30 分)

1、题面:

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

2、题意:

给出树的中序、前序,然后询问u,v的lca

3、正解:

1、不建树,直接递归查找 https://blog.csdn.net/liuchuo/article/details/82560863

2、建树,并查集暴力lca,需要离散化

4、错误:

用建树写的,然后被离散搞蒙了

5、思维:

建树实际上不需要保存左右节点,因为lca只要知道是不是父子即可

开始担心暴力会不会T,事实证明PAT时间还是挺宽裕的

 

题目里说是distinct 数字,所以会有负数之类的数字出现,如果用数组做并查集,只能离散化

6、代码:

#include<bits/stdc++.h>

using namespace std;

const int N=1e5+10;

int pre[N]={0},mid[N]={0},fa[N]={0},n,m,chk[N];

void work(int l,int r,int &p,int f){

    if(l>r || p>n) return ;

    p++;

    int i;

    for(i=l;i<=r;i++)

        if(mid[i] == pre[p]) break;

    if(i==r+1){

        p--;return ;

    }

    fa[ pre[p] ] = f;

    work(1,i-1,p,mid[i]);

    work(i+1,r,p,mid[i]);

}

int lca(int a,int b){//并查集暴力lca

    memset(chk,0,sizeof(chk));

    while(fa[a]!=a) chk[a]=1,a=fa[a];

    while(fa[b]!=b){

        if(chk[b]==1) return b;

        b = fa[b];

    }

}

struct node{

    int id,val;

    node(){;}

    node(int a,int b){id = a; val = b;}

    bool operator<(const node &b)const{

        return val < b.val;

    }

}num[N];

int main(){

    int a,b,c=0;

    cin>>m>>n;

    for(int i=1;i<=n;i++) scanf("%d",&num[i].val),num[i].id = i;

    sort(num+1,num+1+n);//离散化

    for(int i=1;i<=n;i++) mid[ num[i].id ] = i;

    for(int i=1;i<=n;i++) scanf("%d",&num[i].val),num[i].id = i;

    sort(num+1,num+1+n);//离散化

    for(int i=1;i<=n;i++) pre[ num[i].id ] = i;

    work(1,n,c,pre[1]);

    for(int i=1;i<=m;i++){

        int t = 0,A,B,T;

        scanf("%d %d",&a,&b);

        A = lower_bound(num+1,num+1+n,node(0,a))-num;

        B = lower_bound(num+1,num+1+n,node(0,b))-num;   

        if(num[A].val!=a) t++;

        if(num[B].val!=b) t++;

        if(t==2){

            printf("ERROR: %d and %d are not found.\n",a,b);

        }else if(t==1){

            printf("ERROR: %d is not found.\n",num[A].val!=a?a:b);

        }else{

            T = lca(A,B);//T->离散化后的值

            t = num[T].val;

            if(t == a || t==b){

                printf("%d is an ancestor of %d.\n",t==a?a:b,t==a?b:a);

            }else{

                printf("LCA of %d and %d is %d.\n",a,b,t);

            }

        }   

    }

}

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值