Pagini recente » Cod sursa (job #2630970) | Statistici UBB Popovici Craciun Patcas (UBB_Popovici_Craciun_Patcas) | Cod sursa (job #3194756) | Cod sursa (job #2516785) | Cod sursa (job #3289594)
#include <fstream>
using namespace std;
const int nmax = 1e5;
const int lmax = 17;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m, l, u, v, dp[lmax + 1][nmax + 1], depth[nmax + 1];
int lca(int u, int v) {
if (depth[u] < depth[v])
swap(u, v);
// ridicam u la aceeasi inaltime ca v
for (int p = l - 1; p >= 0; p--) {
if (depth[u] - (1 << p) >= depth[v]) {
u = dp[p][u];
}
}
if (u == v)
return u;
// ridicam u si v in paralel pana ajung imediat sub lca
for (int p = l - 1; p >= 0; p--) {
if (dp[p][u] != 0 && dp[p][u] != dp[p][v]) {
u = dp[p][u];
v = dp[p][v];
}
}
// parintele lor comun este lca
return dp[0][v];
}
void precalc() {
while ((1 << l) <= n)
l++;
for (int i = 1; i < l; i++) {
for (int j = 1; j <= n; j++) {
int prv = dp[i - 1][j];
if (prv != 0)
dp[i][j] = dp[i - 1][prv];
}
}
}
int calc_depth(int node) {
if (depth[node] != 0 || node == 1)
return depth[node];
return depth[node] = 1 + calc_depth(dp[0][node]);
}
int main() {
fin >> n >> m;
for (int i = 2; i <= n; i++)
fin >> dp[0][i];
for (int i = 1; i <= n; i++)
depth[i] = calc_depth(i);
precalc();
while (m--) {
fin >> u >> v;
fout << lca(u, v) << '\n';
}
return 0;
}