这题比 1151 简单一点,因为给出的是 BST,它的中序遍历是非减的,从而在判断两结点是否在当前根结点的两侧时,可以直接比较大小来判断。
比较坑的是,必须要先找到合适的范围,然后输出答案,而不能边遍历(或递归)边判断是否该输出,会有个点超时。我真的想不明白就这一组 If else 判断居然能超时。
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e4+4;
int m, n;
int pre[maxn];
map<int, bool> isExist;
void read() {
scanf("%d%d", &m, &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &pre[i]);
isExist[pre[i]] = true;
}
}
void find(int u, int v) {
int rt;
for (int i = 1; i <= n; ++i) {
rt = pre[i];
// 先找到合适的范围,否则会超时一个点
if ((u >= rt && v <= rt) || (u <= rt && v >= rt)) break;
}
if (!isExist[u] && isExist[v]) { //先检查u、v是否存在
printf("ERROR: %d is not found.\n", u);
} else if (isExist[u] && !isExist[v]) {
printf("ERROR: %d is not found.\n", v);
} else if (!isExist[u] && !isExist[v]) {
printf("ERROR: %d and %d are not found.\n", u, v);
} else if (u == rt || v == rt) {
printf("%d is an ancestor of %d.\n", rt, u == rt ? v : u);
} else if ((u > rt && v < rt) || (u < rt && v > rt)) {
printf("LCA of %d and %d is %d.\n", u, v, rt);
}
}
void solve() {
while (m--) {
int u, v;
scanf("%d%d", &u, &v);
find(u, v);
}
}
int main() {
read();
solve();
return 0;
}