Pagini recente » Cod sursa (job #2343409) | Cod sursa (job #3180218) | Cod sursa (job #2864934) | Cod sursa (job #2025008) | Cod sursa (job #3216340)
#include <iostream>
#include <fstream>
#define MAXN 100000
#define LOGN 17
#define DEBUG 0
using namespace std;
FILE *fout, *fin;
int d[MAXN][LOGN], niv[MAXN];
int getNiv(int id){
if(niv[id] != -1)
return niv[id];
niv[id] = getNiv(d[id][0]) + 1;
return niv[id];
}
void stramosi(){
int n, q;
fscanf(fin, "%d%d", &n, &q);
for(int i = 1; i < n; i ++){
fscanf(fin, "%d", &d[i][0]);
d[i][0] --;
}
for(int j = 1; (1 << j) < n; j ++){
for(int i = 1; i < n; i ++){
d[i][j] = d[ d[i][j - 1] ][j - 1];
}
}
for(int i = 0; i < n; i ++){
niv[i] = -1;
}
niv[0] = 0;
for(int i = 0; i < n; i ++){
getNiv(i);
}
if(DEBUG){
printf("Nivel: ");
for(int i = 0; i < n; i ++){
printf("%d ", getNiv(i));
}
printf("\n\n");
for(int i = 0; i < n; i ++){
for(int j = 0; (1 << j) < n; j ++)
printf("%d ", d[i][j]);
printf("\n");
}
}
fflush(NULL);
int logn = 0;
while((1 << (logn+1)) < n)
logn ++;
for(int i = 0; i < q; i ++){
int x, y;
fscanf(fin, "%d%d", &x, &y);
x --;
y --;
// Aduc nodurile la acelasi nivel
while(getNiv(x) > getNiv(y))
x = d[x][0];
while(getNiv(x) < getNiv(y))
y = d[y][0];
int j = logn;
if(x == y)
fprintf(fout, "%d\n", x + 1);
else{
// Caut stramosul comun
while(d[x][0] != d[y][0]){
fflush(NULL);
if(d[x][j] != d[y][j]){
x = d[x][j];
y = d[y][j];
}
j --;
}
fprintf(fout, "%d\n", d[x][0] + 1);
}
}
}
int main(){
fin = fopen("lca.in", "r");
fout = fopen("lca.out", "w");
stramosi();
fclose(fin);
fclose(fout);
return 0;
}