/*
问题代码
思路:将问题转换为求链表的第一个公共子节点
*/
#include<iostream>
#include<cstring>
#include<unordered_map>
using namespace std;
int n, m;
const int N = 10010;
int in[N], pre[N];
int l[N], r[N];
unordered_map<int, int> pos, father;
unordered_map<int, bool> st, mark;
//bool mark[N]; //问题代码:无法标记负数,可以用unordered_map代替
int build(int pl, int pr, int il, int ir){
if(pl > pr) return 0;
int u = pre[pl];
int k = pos[u];
int num = k - il;
l[u] = build(pl + 1, pl + num, il, k - 1);
r[u] = build(pl + num + 1, pr, k + 1, ir);
return u;
}
void dfs(int u){
if(!u) return;
father[l[u]] = u, dfs(l[u]);
father[r[u]] = u, dfs(r[u]);
}
int find(int &a, int &b, int root){
int t1 = a, t2 = b;
if(t1 == t2) return t1;
while(t1){
mark[t1] = true;
if(t1 == root) break;
t1 = father[t1];
}
while(t2){
if(mark[t2]) return t2;
t2 = father[t2];
}
}
int main(){
cin >> m >> n;
for(int i = 0; i < n; i++ ) {cin >> in[i]; pos[in[i]] = i;}
for(int i = 0; i < n; i++) {cin >> pre[i]; st[pre[i]] = true;}
int root = build(0, n - 1, 0, n - 1);
dfs(root);
for(int j = 0; j < m ; j ++){
int a , b;
cin >> a >> b;
//memset(mark, false, sizeof mark);
mark.clear();
if(!st[a] && !st[b]) printf("ERROR: %d and %d are not found.\n", a, b);
else if(!st[a]) printf("ERROR: %d is not found.\n", a);
else if(!st[b]) printf("ERROR: %d is not found.\n", b);
else{
int t = find(a, b, root);
if(t != b && t != a) printf("LCA of %d and %d is %d.\n", a, b, t);
else if(t == b && t != a) printf("%d is an ancestor of %d.\n", b, a);
else if(t != b && t == a) printf("%d is an ancestor of %d.\n", a, b);
else printf("%d is an ancestor of %d.\n", a, b);
}
}
return 0;
}
过不了