Pagini recente » Cod sursa (job #459687) | Cod sursa (job #3165685) | Cod sursa (job #514682) | Cod sursa (job #603688) | Cod sursa (job #2653878)
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
using namespace std;
vector<vector<int>> c;
vector<int> level, euler, first;
vector<vector<int>> g;
int lca(int x, int y) {
if (first[x] > first[y])
swap(x, y);
int lg = 0;
//cout << first[x] << ' ' << first[y] << '\n';
while ((1 << (lg + 1)) < first[y] - first[x] + 1) ++lg;
//cout << lg << '\n';
x = c[first[x]][lg];
y = c[first[y] - (1<<lg) + 1][lg];
//cout << x << ' ' << y << '\n';
if (level[x] < level[y])
return x;
return y;
}
void dfs(int u, int l) {
level[u] = l;
euler.push_back(u);
first[u] = euler.size() - 1;
for (auto v : g[u]) {
dfs(v, l + 1);
euler.push_back(u);
}
}
void Init() {
for (int i = 0;i < c.size();++i)
c[i][0] = euler[i];
for(int j=1;(1<<j)<c.size();++j)
for (int i = 0;i + (1 << j) < c.size();++i) {
int x = c[i][j - 1], y = c[i + (1 << (j - 1))][j - 1];
if (level[x] < level[y])
c[i][j] = x;
else c[i][j] = y;
}
/*for (int i = 0;i < c.size();++i) {
for (int j = 0;j < 5;++j)
cout << c[i][j] << ' ';
cout << '\n';
}*/
}
int main() {
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m;
fin >> n >> m;
g.resize(n + 1);
level.resize(n + 1, -1);
first.resize(n + 1, -1);
for (int i = 2;i <= n;++i) {
int x;
fin >> x;
g[x].push_back(i);
}
dfs(1, 1);
/*for (auto x : euler)
cout << x << ' ';
cout << '\n';*/
c.resize(euler.size());
for (int i = 0;i < c.size();++i)
c[i].resize(20, -1);
Init();
while (m--) {
int x, y;
fin >> x >> y;
fout << lca(x, y) << '\n';
}
return 0;
}