Cod sursa(job #1844687)

Utilizator NarniussAnghelache Bogdan Narniuss Data 10 ianuarie 2017 12:23:58
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.43 kb
#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;
}