题意:

给出一棵二叉搜索树的前序遍历,问结点u和v的共同最低祖先是谁,利用先序遍历特点。
二叉搜索树满足:
节点的左子树只包含键小于节点键的节点。
节点的键只包含节点的右键大于或等于子树的节点的键。
左子树和右子树也必须是二叉搜索树。

题解:

样例:
6 3 1 2 5 4 8 7
根据题目要求我们可以得到:
在这里插入图片描述
红字则是该数字在前序遍历中出现的顺序(从0开始)
我们可以从题目要求下手,在本题中,根的左子树总是小于根,右子树总是大于根
查询u和v的lca,如果一个x(x不与u和v重合)同时满足x>u,x<v,说明u在x的左边,v在x的右边,那说明x就是u和v的lca
同理。x<u,x>v也是
当然x和u或v重合时也是

代码:

#include<bits/stdc++.h>
using namespace std;
map<int,bool> mp;
int main(){
    int m,n,u,v,a;
    cin>>m>>n;
    vector<int> pre(n);
    for (int i=0;i<n;i++){
        cin>>pre[i];
        mp[pre[i]]=true;
    }
    for (int i=0;i<m;i++)
    {
        cin>>u>>v;
        for (int j=0;j<n;j++)
        {
            a=pre[j];
            if ((a>u&&a<v)||(a>v&&a<u)||(a==u)||(a==v))break;
        }
        if (mp[u]==false&&mp[v]==false)
            printf("ERROR: %d and %d are not found.\n",u,v);
        else if (mp[u] == false || mp[v] == false)
            printf("ERROR: %d is not found.\n", mp[u] == false ? u : v);
        else if (a == u || a == v)
            printf("%d is an ancestor of %d.\n", a, a == u ? v : u);
        else
            printf("LCA of %d and %d is %d.\n", u, v, a);
    }
    return 0;
}