Pagini recente » Cod sursa (job #2881559) | Cod sursa (job #2971573) | Cod sursa (job #1975141) | Cod sursa (job #2594603) | Cod sursa (job #2653758)
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
using namespace std;
vector<vector<int>> c;
vector<int> p, level;
int lca(int x, int y) {
if (level[x] < level[y])
swap(x, y);
int lg = 18;
while (level[x] > level[y]) {
--lg;
if (c[x][lg] != -1) {
if (level[c[x][lg]] >= level[y])
x = c[x][lg];
}
}
//cout << x << ' ' << y << ' ' << lg << '\n';
if (x == y)
return x;
lg = 18;
while (p[x] != p[y]) {
--lg;
//cout << x << ' ' << y << ' ' << lg << '\n';
if (c[x][lg] != c[y][lg]) {
x = c[x][lg];
y = c[y][lg];
}
}
return p[x];
}
void Init() {
int n = c.size() - 1;
for (int i = 1;i <= n;++i)
c[i][0] = p[i];
for (int j = 1;(1 << j) < n;++j)
for (int i = 1;i <= n;++i)
if (level[i] - (1 << j) > 0) {
c[i][j] = c[c[i][j - 1]][j - 1];
}
/*for (int i = 1;i <= n;++i) {
cout << i << " : ";
for (int j = 0;j < 5;++j)
cout << c[i][j] << ' ';
cout << '\n';
}*/
}
int findLevel(int root) {
if (level[root] != -1) return level[root];
level[root] = findLevel(p[root]) + 1;
return level[root];
}
int main() {
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m;
fin >> n >> m;
p.resize(n + 1, -1);
level.resize(n + 1, -1);
c.resize(n + 1);
for (int i = 1;i <= n;++i)
c[i].resize(19, -1);
for (int i = 2;i <= n;++i) {
int x;
fin >> x;
p[i] = x;
}
level[1] = 1;
for (int i = 2;i <= n;++i)
findLevel(i);
Init();
while (m--) {
int x, y;
fin >> x >> y;
fout << lca(x, y) << '\n';
}
return 0;
}