Pagini recente » Cod sursa (job #2306026) | Cod sursa (job #1841442) | Cod sursa (job #1975737) | Cod sursa (job #1674881) | Cod sursa (job #1673673)
#include <iostream>
#include <cstdio>
using namespace std;
const int N_max = 100002;
const int M_max = 2000002;
const int Log = 18;
int urm[N_max];
int vf[N_max];
int lst[N_max];
int nr;
int level[N_max];
bool viz[N_max];
int tata[N_max];
int A[N_max][Log]; /* A[i][j] == AL 2 ^ j STRAMOS AL LUI i */
int N, Q;
void adauga(int x, int y)
{
// ADAUGA IN LISTA LUI x PE y
nr++;
vf[nr] = y;
urm[nr] = lst[x];
lst[x] = nr;
}
void read()
{
int i, j;
scanf("%d %d", &N, &Q);
for(i = 2; i <= N; i++)
{
scanf("%d", &tata[i]);
adauga(tata[i], i);
}
/* CONSTRUIESC MATRICEA A */
for(i = 1; i <= N; i++) A[i][0] = tata[i]; /* PRIMUL STRAMOS AL LUI i ESTE CHIAR TATALUI ACESTUIA */
for(i = 1; i <= N; i++)
for(j = 1; (1 << j) <= N; j++)
if(A[i][j - 1]) A[i][j] = A[A[i][j - 1]][j - 1];
}
void dfs(int x)
{
int p, y;
viz[x] = true;
// PARCURG VECINII y AI LUI x
p = lst[x];
while(p != 0)
{
y = vf[p];
if(!viz[y])
{
level[y] = 1 + level[x];
dfs(y);
}
p = urm[p];
}
}
int lca(int p, int q)
{
int j;
if(level[p] < level[q]) swap(p, q);
int lg1, lg2;
for(lg1 = 0; (1 << lg1) <= level[p]; lg1++);
lg1--;
for(lg2 = 0; (1 << lg2) <= level[q]; lg2++);
lg2--;
for(j = lg1; j >= 0; j--)
if(A[p][j] && level[A[p][j]] >= level[q]) /* EXISTA AL 2 ^ j STRAMOS AL LUI p && NIVELUL CELUI DE-AL 2 ^ j STRAMOS AL LUI p ESTE >= DECAT NIVELUL LUI q */
p = A[p][j];
if(p == q) return p;
/* ACUM p SI q SUNT LA ACELASI NIVEL */
for(j = lg2; j >= 0; j--)
if(A[p][j] && A[p][j] != A[q][j]) /* EXISTA AL 2 ^ j STRAMOS AL LUI p SI NU MERG "PREA SUS" */
{
p = A[p][j];
q = A[q][j];
}
/* SUNT LA UN NIVEL SUB DE lca(p, q) */
return tata[p];
}
void query()
{
int i, p, q;
for(i = 1; i <= Q; i++)
{
scanf("%d %d", &p, &q);
int ans = lca(p, q);
printf("%d\n", ans);
}
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
read();
dfs(1);
query();
return 0;
}