Pagini recente » Cod sursa (job #2852955) | Cod sursa (job #698481) | Cod sursa (job #1903440) | Cod sursa (job #1483229) | Cod sursa (job #2834493)
#include <stdio.h>
#include <algorithm>
using namespace std;
#define MAXN 100000
int parents[MAXN + 1][17];
int level[MAXN + 1];
int lg[MAXN + 1];
void precalcLog(int n) {
int i;
for ( i = 2; i <= n; i++)
lg[i] = lg[i / 2] + 1;
}
int calcLevel(int pos) {
int result;
result = 0;
while ( pos > 1 )
result++, pos = parents[pos][0];
return result;
}
void bringToSameLevel(int& a, int& b) {
int nr, ok = false;
if ( level[a] > level[b] )
swap(a, b);
if ( a + b == 21 )
ok = true;
while ( level[a] < level[b] ) {
nr = lg[level[b] - level[a]];
b = parents[b][nr];
}
}
int lca(int a, int b) {
int i;
bringToSameLevel(a, b);
while ( a != b ) {
i = 0;
do
i++;
while ( i <= lg[level[a]] && parents[a][i] != parents[b][i] );
i--;
a = parents[a][i];
b = parents[b][i];
}
return a;
}
int main() {
FILE *fin, *fout;
fin = fopen("lca.in", "r");
fout = fopen("lca.out", "w");
int n, m, i, i2, a, b;
fscanf(fin, "%d%d", &n, &m);
precalcLog(n);
for ( i = 2; i <= n; i++ ) {
fscanf(fin, "%d", &parents[i][0]);
}
for ( i = 2; i <= n; i++ )
level[i] = calcLevel(i);
for ( i = 2; i <= n; i++ ) {
for ( i2 = 1; i2 <= lg[level[i]]; i2++ ) {
parents[i][i2] = parents[parents[i][i2 - 1]][i2 - 1];
}
}
for ( i = 0; i < m; i++ ) {
fscanf(fin, "%d%d", &a, &b);
fprintf(fout, "%d\n", lca(a, b));
}
fclose(fin);
fclose(fout);
return 0;
}