Pagini recente » Cod sursa (job #1890761) | Cod sursa (job #677826) | Borderou de evaluare (job #804952) | Cod sursa (job #2232407) | Cod sursa (job #1198251)
#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
vector<vector<int>> adjl;
vector<int> path;
vector<int> index;
vector<int> level;
vector<vector<int>> table;
void build_euler_path(int u, int lvl)
{
level[u] = lvl;
index[u] = path.size();
path.push_back(u);
for (auto v: adjl[u]) {
build_euler_path(v, lvl+1);
path.push_back(u);
}
}
int highest(int u, int v)
{
return level[u] <= level[v] ? u : v;
}
void build_table()
{
int size = log2(path.size()-1)+1;
table.resize(size);
table[0] = path;
for (int i = 1; i < size; i++) {
int stp = 1<<i;
table[i].resize(path.size()-stp);
for (int j = table[i].size()-1; j >= 0; j--) {
table[i][j] = highest(table[i-1][j], table[i-1][j+stp/2]);
}
}
}
int lca(int u, int v)
{
if (u == v) {
return u;
}
int x = min(index[u], index[v]);
int y = max(index[u], index[v]);
int lg = log2(y-x);
return highest(table[lg][x], table[lg][y-(1<<lg)+1]);
}
int main()
{
ios::sync_with_stdio(false);
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
int n, m;
cin >> n >> m;
adjl.resize(n);
for (int i = 1; i < n; i++) {
int p;
cin >> p;
p--;
adjl[p].push_back(i);
}
index.resize(n);
level.resize(n);
build_euler_path(0, 0);
build_table();
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
u--, v--;
printf("%d\n", lca(u, v)+1);
}
return 0;
}