Pagini recente » Cod sursa (job #1643934) | Cod sursa (job #874493) | Cod sursa (job #491885) | Cod sursa (job #1209904) | Cod sursa (job #3128984)
#include <fstream>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int N, M, v[250100], a[30][250100], ad[250100];
int calculareAdancime(int x) {
if (ad[x] == -1)
ad[x] = calculareAdancime(v[x]) + 1;
return ad[x];
}
void generare() {
for (int i = 1; i <= N; i++)
ad[i] = -1;
for (int i = 1; i <= N; i++)
a[1][i] = v[i];
for (int i = 2; (1 << (i - 1)) <= N; i++) {
for (int j = 1; j <= N; j++) {
a[i][j] = a[i - 1][a[i - 1][j]];
}
}
for (int i = 1; i <= N; i++)
calculareAdancime(i);
};
int query(int p, int q) {
int nod = p;
for (int i = 1; i <= 20; i++) {
if (q & (1 << (i - 1))) {
nod = a[i][nod];
}
}
return nod;
}
int lca(int p, int q) {
int answer = -1;
if (ad[p] < ad[q])
q = query(q, ad[q] - ad[p]);
else if (ad[p] > ad[q])
p = query(p, ad[p] - ad[q]);
if (p == q)
return p;
int l = 1, r = ad[q];
while (l <= r) {
int mid = (l + r) / 2;
if (query(p, ad[p] - mid) == query(q, ad[q] - mid)) {
l = mid + 1;
answer = mid;
}
else
r = mid - 1;
}
return query(p, ad[p] - answer);
}
int main()
{
fin >> N >> M;
for (int i = 2; i <= N; i++)
fin >> v[i];
generare();
for (int i = 1; i <= M; i++) {
int p, q;
fin >> p >> q;
fout << lca(p, q) << '\n';
}
return 0;
}