题意:

给出一棵二叉搜索树的前序遍历,问结点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;
}