Pagini recente » Cod sursa (job #509741) | Cod sursa (job #2039898) | Cod sursa (job #2040406) | Cod sursa (job #1849546) | Cod sursa (job #1998484)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int MAXN = 1e5 + 5;
int n, m;
int depth[MAXN], parent[MAXN], pos[MAXN], log[2 * MAXN], ePath[2 * MAXN], eSize;
int dp[18][2 * MAXN];
vector<int> g[MAXN];
void set_log() {
int next = 2;
int lg = 0;
for (int i = 1; i <= eSize; ++i) {
if (i == next) {
lg++;
next *= 2;
}
log[i] = lg;
}
}
void set_level(int x, int lvl) {
depth[x] = lvl;
for (int i = 0; i < g[x].size(); ++i) {
int y = g[x][i];
if (y != parent[x]) set_level(y, lvl + 1);
}
}
void euler_dfs(int x) {
pos[x] = eSize;
ePath[eSize++] = x;
for (int i = 0; i < g[x].size(); ++i) {
int y = g[x][i];
if (y != parent[x]) {
euler_dfs(y);
ePath[eSize++] = x;
}
}
}
void rmq() {
//for (int i = 0; i <= log[eSize]; ++i) dp[i] = new int[eSize]();
for (int i = 0; i < eSize; ++i) dp[0][i] = ePath[i];
for (int k = 1; k <= log[eSize]; ++k) {
int mid = 1 << (k - 1);
for (int i = 0; i < eSize - mid; ++i) {
if (depth[dp[k-1][i]] < depth[dp[k - 1][i + mid]]) {
dp[k][i] = dp[k-1][i];
} else {
dp[k][i] = dp[k - 1][i + mid];
}
}
}
}
int query(int x, int y) {
int length = pos[y] - pos[x] + 1;
int lg = log[length];
int dif = length - (1 << lg);
if (depth[dp[lg][pos[x]]] < depth[dp[lg][pos[x] + dif]]) {
return dp[lg][pos[x]];
} else {
return dp[lg][pos[x] + dif];
}
}
int main()
{
in >> n >> m;
for (int i = 2, x; i <= n; ++i) {
in >> x;
parent[i] = x;
g[i].push_back(x);
g[x].push_back(i);
}
set_level(1, 1);
euler_dfs(1);
set_log();
rmq();
for (int i = 1, x, y; i <= m; ++i) {
in >> x >> y;
if (pos[x] > pos[y]) swap(x, y);
out << query(x, y) << "\n";
}
return 0;
}