Pagini recente » Cod sursa (job #2029684) | Cod sursa (job #135780) | Cod sursa (job #2114340) | Cod sursa (job #162724) | Cod sursa (job #2604865)
#include <iostream>
#include <fstream>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int N = 100001;
const int L = 18;
int n, m, nr, ne, vf[N], urm[N], lst[N], rmq[L][2 * N], level[N], first[N], e[2 * N], logaritm[2 * N];
// matricea t va tine al 2-lea stramos al lui j, t[i][j]
void add(int x, int y) {
vf[++nr] = y;
urm[nr] = lst[x];
lst[x] = nr;
}
void dfs(int x) {
e[++ne] = x;
first[x] = ne; // prima pozitie pe care apare fiecare nod
int y;
for (int p = lst[x]; p != 0; p = urm[p]) {
y = vf[p];
if (first[y] == 0) { // nu am mai fost pe acolo
level[y] = 1 + level[x];
dfs(y);
e[++ne] = x;
}
}
}
int lca(int x, int y) {
int p = first[x];
int q = first[y];
if (p > q) swap(p, q);
int l = logaritm[q - p + 1];
int st = rmq[l][p + (1 << l) - 1];
int dr = rmq[l][q];
int rez = st;
if (level[e[dr]] < level[e[rez]]) rez = dr; // pozitia din euler
return e[rez];
}
int main() {
in >> n >> m;
for (int i = 2; i <= n; i++) {
int a;
in >> a;
add(a, i);
}
logaritm[1] = 0;
for (int i = 2; i <= 2 * n; i++)
logaritm[i] = 1 + logaritm[i / 2];
dfs(1);
for (int j = 1; j < 2 * n; j++) {
rmq[0][j] = j;
}
for (int i = 1; (1 << i) < 2 * n; i++) {
for (int j = 1 << i; j < 2 * n; j++) {
int st = rmq[i - 1][j - (1 << (i - 1))];
int dr = rmq[i - 1][j];
if (level[e[st]] <= level[e[dr]]) rmq[i][j] = st;
else rmq[i][j] = dr;
}
}
for (int i = 1; i <= m; i++) {
int x, y;
in >> x >> y;
out << lca(x, y) << '\n';
}
return 0;
}