Pagini recente » Cod sursa (job #2396066) | Cod sursa (job #2596053) | Cod sursa (job #1767814) | Cod sursa (job #1464742) | Cod sursa (job #925631)
Cod sursa(job #925631)
#include <cstdio>
#include <cassert>
#include <vector>
using namespace std;
#define MAX_N 100001
#define LOG_MAX_N 20
#define MAX_S 600001
int n, m;
int father[LOG_MAX_N][MAX_N];
vector <int> v[MAX_N];
int level[MAX_N];
char s[MAX_S];
void read() {
assert(scanf("%d%d\n", &n, &m) == 2);
gets(s);
int node = 2;
for (int i = 0; s[i]; ++i)
if (s[i] == ' ')
++node;
else
father[0][node] = father[0][node] * 10 + s[i] - '0';
for (int i = 2; i <= n; ++i)
v[father[0][i]].push_back(i);
}
void set_father() {
for (int j = 1; (1 << j) <= n; ++j)
for (int i = 1; i <= n; ++i)
father[j][i] = father[j - 1][father[j - 1][i]];
}
void dfs(int node, int lvl) {
level[node] = lvl;
for (vector <int>::iterator it = v[node].begin(); it != v[node].end(); ++it)
dfs(*it, lvl + 1);
}
int lca(int a, int b) {
if (a == b)
return a;
if (level[a] < level[b])
swap(a, b);
int log_a = 1, log_b = 1;
while (1 << log_a < level[a])
++log_a;
while (1 << log_b < level[b])
++log_b;
for (int i = log_a; i >= 0; --i)
if (level[a] - (1 << i) >= level[b])
a = father[i][a];
if (a == b)
return a;
for (int i = log_b; i >= 0; --i)
if (father[i][a] && father[i][a] != father[i][b]) {
a = father[i][a];
b = father[i][b];
}
return father[0][a];
}
int main() {
assert(freopen("lca.in", "r", stdin));
assert(freopen("lca.out", "w", stdout));
read();
set_father();
dfs(1, 1);
while (m) {
int a, b;
assert(scanf("%d%d", &a, &b) == 2);
printf("%d\n", lca(a, b));
--m;
}
}