题意:给出一个bst的先序,给一些点对,求这些点对的lca。
思路:建树,lca必然在两个点对值中间,根据这个性质搜索树。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAX_N = 10100;
int M, N, x, y, r;
int a[MAX_N];
int lc[MAX_N], rc[MAX_N];
bool f1, f2;
int build(int lo, int hi) {
if (lo >= hi) return -1;
if (hi-lo==1) return lo;
int p = hi;
for (int i = lo+1; i < hi; i++) {
if (a[lo] <= a[i]) {
p = i; break;
}
}
lc[lo] = build(lo+1, p);
rc[lo] = build(p, hi);
return lo;
}
bool Find(int r, int x) {
if (r == -1) return false;
if (a[r] == x) return true;
if (a[r] < x) return Find(rc[r], x);
else return Find(lc[r], x);
}
int lca(int x, int y, int r) {
if (y < x) swap(x, y);
while (!(x<=a[r]&&a[r]<=y)) {
if (a[r] < x) {
r = rc[r];
} else if (a[r] > y) {
r = lc[r];
}
}
return r;
}
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
scanf("%d %d", &M, &N);
memset(lc, -1, sizeof(lc)); memset(rc, -1, sizeof(rc));
for (int i = 0; i < N; i++) {
scanf("%d", &a[i]);
}
r = build(0, N);
for (int i = 0; i < M; i++) {
scanf("%d %d", &x, &y);
f1 = Find(r, x); f2 = Find(r, y);
if (!f1 || !f2) {
if (!f1 && !f2) {
printf("ERROR: %d and %d are not found.\n", x, y);
} else if (!f1) {
printf("ERROR: %d is not found.\n", x);
} else {
printf("ERROR: %d is not found.\n", y);
}
} else {
int t = lca(x, y, r);
if (a[t] == x) {
printf("%d is an ancestor of %d.\n", x, y);
} else if (a[t] == y) {
printf("%d is an ancestor of %d.\n", y, x);
} else {
printf("LCA of %d and %d is %d.\n", x, y, a[t]);
}
}
}
return 0;
}