Pagini recente » Cod sursa (job #2287238) | Istoria paginii moisil-2015/inception | Istoria paginii utilizator/mihnea_toader | Cod sursa (job #189530) | Cod sursa (job #2392543)
#include <cmath>
#include <vector>
#include <fstream>
#define LMAX 20
#define NMAX 200010
std::ifstream fin("lca.in");
std::ofstream fout("lca.out");
int n;
bool vis[NMAX];
std::vector<int> ad[NMAX];
int len;
int arr[NMAX];
int lvl[NMAX];
int pos[NMAX];
int q;
int dp[NMAX][LMAX];
int rmq(int lo, int hi) {
int k = log2(hi - lo + 1);
if (lvl[dp[lo][k]] < lvl[dp[hi - (1 << k) + 1][k]])
return arr[dp[lo][k]];
return arr[dp[hi - (1 << k) + 1][k]];
}
void dfs(int node, int depth) {
vis[node] = true;
arr[++len] = node;
lvl[len] = depth;
pos[node] = len;
for (int nghb : ad[node])
if (!vis[nghb]) {
dfs(nghb, depth + 1);
arr[++len] = node;
lvl[len] = depth;
}
}
int main() {
fin >> n >> q;
for (int i = 2; i <= n; i++) {
int x; fin >> x;
ad[i].push_back(x);
ad[x].push_back(i);
}
dfs(1, 1);
for (int i = 1; i <= len; i++)
dp[i][0] = i;
for (int i = len; i >= 1; i--)
for (int j = 1; i + (1 << j) - 1 <= len; j++)
if (lvl[dp[i][j - 1]] < lvl[dp[i + (1 << (j - 1))][j - 1]])
dp[i][j] = dp[i][j - 1];
else
dp[i][j] = dp[i + (1 << (j - 1))][j - 1];
for (int it = 0; it < q; it++) {
int x, y;
fin >> x >> y;
if (pos[x] < pos[y])
fout << rmq(pos[x], pos[y]) << '\n';
else
fout << rmq(pos[y], pos[x]) << '\n';
}
fout.close();
return 0;
}