Pagini recente » Cod sursa (job #292203) | Cod sursa (job #866255) | Cod sursa (job #2324893) | Cod sursa (job #1680052) | Cod sursa (job #2447070)
#include <bits/stdc++.h>
using namespace std;
class Tree {
vector< vector<int> >G;
vector< vector<int> > jump;
vector<int>First, Last, eulert, depth;
int tmr, root;
public:
Tree(const int n = 0) : G(n), jump(20, vector<int>(n)), First(n), Last(n), eulert(n), depth(n) {
tmr = 0;
root = 0;
}
void AddEdge(int x, int y) {
assert(0 <= x && x < (int)G.size());
assert(0 <= y && y < (int)G.size());
G[x].push_back(y);
G[y].push_back(x);
}
void dfs(int u, int par, int dep) {
depth[u] = dep;
jump[0][u] = par;
First[u] = tmr++;
eulert.push_back(u);
for(int i = 1; i < 20; ++i)
if(jump[i - 1][u] != -1)
jump[i][u] = jump[i - 1][jump[i - 1][u]];
for(int v: G[u])
if(v != par)
dfs(v, u, dep + 1);
eulert.push_back(u);
Last[u] = tmr++;
}
int LCA(int a, int b) {
if(depth[a] < depth[b])
swap(a, b);
for(int i = 19; i >= 0; --i)
if(depth[a] - (1 << i) >= depth[b])
a = jump[i][a];
if(a == b)
return a;
for(int i = 19; i >= 0; --i)
if(jump[i][a] != -1 && jump[i][b] != -1 && jump[i][a] != jump[i][b]) {
a = jump[i][a];
b = jump[i][b];
}
assert(a != root);
return jump[0][a];
}
void Init() {
dfs(root, -1, 0);
}
};
int main() {
ifstream cin("lca.in");
ofstream cout("lca.out");
int n, q;
cin >> n >> q;
Tree tree(n);
for(int i = 1; i < n; ++i) {
int father;
cin >> father;
tree.AddEdge(father-1, i);
}
tree.Init();
for(int i = 0; i < q; ++i) {
int u, v;
cin >> u >> v;
cout << tree.LCA(u - 1, v - 1) + 1 << '\n';
}
return 0;
}