Pagini recente » Cod sursa (job #2690577) | Cod sursa (job #2769169) | Cod sursa (job #2747988) | Cod sursa (job #2755594) | Cod sursa (job #2834511)
#include <stdio.h>
#include <algorithm>
using namespace std;
#define MAXN 100000
int parents[MAXN + 1][17];
int level[MAXN + 1];
int lg[MAXN + 1];
FILE *fin, *fout;
int readNumber() {
char ch;
int nr;
nr = 0;
ch = fgetc(fin);
while ( ch != ' ' && ch != '\n' && ch != EOF ) {
nr = nr * 10 + ch - '0';
ch = fgetc(fin);
}
return nr;
}
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;
if ( level[a] > level[b] )
swap(a, b);
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);
if ( a != b ) {
for ( i = lg[level[a]]; i >= 0; --i ) {
if ( parents[a][i] && parents[a][i] != parents[b][i] )
a = parents[a][i], b = parents[b][i];
}
a = parents[a][0];
}
return a;
}
int main() {
fin = fopen("lca.in", "r");
fout = fopen("lca.out", "w");
int n, m, i, i2, a, b;
n = readNumber();
m = readNumber();
precalcLog(n);
for ( i = 2; i <= n; i++ ) {
parents[i][0] = readNumber();
}
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++ ) {
a = readNumber();
b = readNumber();
fprintf(fout, "%d\n", lca(a, b));
}
fclose(fin);
fclose(fout);
return 0;
}