Pagini recente » Cod sursa (job #1079053) | Cod sursa (job #1031917) | Cod sursa (job #2448700) | Cod sursa (job #880965) | Cod sursa (job #3280411)
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
int lca[20][100005];
int lg2[100005];
int level[100005];
void find_level (int nod) {
int tata = lca[0][nod];
if (tata == 0) return; // Avoid accessing invalid index
if (level[tata] == 0) {
find_level(tata);
}
level[nod] = level[tata] + 1;
}
int main()
{
fin.tie(0); fin.sync_with_stdio(false);
int n, m; fin>>n>>m;
for (int i=2; i<=n; i++) lg2[i]=lg2[i/2]+1;
for (int i=2; i<=n; i++) fin>>lca[0][i];
for (int i=1; i<=lg2[n]; i++) {
for (int j=1; j<=n; j++) {
lca[i][j]=lca[i-1][lca[i-1][j]];
}
}
level[1]=1;
for (int i=2; i<=n; i++) find_level(i);
int x, y;
while (m--) {
fin>>x>>y;
int nivel_x = level[x], nivel_y = level[y];
if (nivel_y>nivel_x) { // nivel_x va fi cel mai mare
swap(x, y);
swap(nivel_x, nivel_y);
}
// cout<<x<<' '<<y<<endl;
int diff = nivel_x - nivel_y;
while (diff!=0) {
int linie = lg2[diff];
x = lca[linie][x];
diff = diff - (1<<lg2[diff]);
}
// cout << x << ' '<<y<<endl<<endl;
nivel_x = nivel_y; // Avem ambele noduri la acelasi nivel
if (x == y) { // Poate am ajuns deja la lca, (un nod este deasupra celuilalt in lantul spre radacina)
fout << x <<'\n';
continue;
}
for (int i = lg2[nivel_x]; i>=0; i--) {
int linie = lg2[i];
if (lca[linie][x]!=lca[linie][y]) {
x = lca[linie][x];
y = lca[linie][y];
nivel_x = level[nivel_x];
nivel_y = level[nivel_y];
}
}
int ans = lca[0][x];
fout<<ans<<'\n';
}
return 0;
}