Pagini recente » Istoria paginii runda/ichb | Cod sursa (job #1515783) | Cod sursa (job #1764006) | Cod sursa (job #3184780) | Cod sursa (job #1844687)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <math.h>
#include <cstdio>
#define NMAX 100002
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int T[NMAX], P[NMAX], L[NMAX],n, q, h, nr;
vector <int> V[NMAX];
void dfs1(int nod)
{
int i;
for(i = 0 ; i < V [nod].size() ; i++){
L[V[nod][i]] = L[nod] + 1;
if(L[V[nod][i]] > h) h = L[V[nod][i]];
dfs1(V[nod][i]);
}
}
void dfs2(int nod)
{
int i;
if(L[nod] < nr){
P[nod] = 1;
}
else
if(L[nod] % nr == 0 ){
P[nod] = T[nod];
}
else{
P[nod] = P[T[nod]];
}
for(i = 0 ; i < V[nod].size() ; i++)
dfs2(V[nod][i]);
}
int lca(int x, int y)
{
//aducem nodurile x si y in aceeasi sectiune(cea mai de sus)
while(P[x] != P[y]){
if(L[x] > L[y])
x = P[x];
else
y = P[y];
}
//acum ca nodurile x si y sunt in aceeasi sectiune
//comparam nivelurile si salvam in noduri tatal lor(LCA-ul)
while(x != y){
if(L[x] > L[y])
x = T[x];
else
y = T[y];
}
return x;
}
int main()
{
fin>>n>>q;
int x, i, y;
for(i = 1 ; i< n ; ++i){
fin>>x;
V[x].push_back(i+1);
T[i+1] = x;
}
//aflam inaltimea maxima, si populam vectorul de nivele
dfs1(1);
nr= sqrt(h);
//populam vectorul P : P[i] = ultimul nod comun din sectiunea de deasupra
dfs2(1);
for(i = 1 ; i <= q ; i++){
fin>>x>>y;
fout<<lca(x, y)<< "\n";
}
return 0;
}