Cod sursa(job #1690019)

Utilizator cristina_borzaCristina Borza cristina_borza Data 14 aprilie 2016 18:10:50
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.52 kb
#include <fstream>
#include <vector>

#define NMAX 200005

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

int tata[NMAX] , nivel[NMAX] , log[2 * NMAX] , t[NMAX][25];
int n , q , x , y;

vector <vector <int> > v;

int lca(int x , int y);
void dfs(int node);

int main() {
    f >> n >> q;

    v.resize(n + 5);
    for(int i = 2 ; i <= n ; ++i) {
      f >> tata[i];
      v[tata[i]].push_back(i);
    }

    nivel[1] = 1;
    dfs(1);
    for(int i = 1 ; i <= n ; ++i) {
      t[i][0] = tata[i];
      for(int j = 1 ; (1 << j) <= nivel[i] ; ++j) {
        t[i][j] = t[t[i][j - 1]][j - 1];
      }
    }

    for(int i = 1 ; i <= 2 * n ; ++i) {
        int aux = 1;
        while((1 << aux) <= i) {
            ++aux;
        }

        log[i] = aux - 1;
    }

    for(int i = 1 ; i <= q ; ++i) {
      f >> x >> y;
      g << lca(x , y) << '\n';
    }
    return 0;
}

int lca(int x , int y) {
  if(nivel[x] < nivel[y]) {
    swap(x , y);
  }

  int dif = nivel[x] - nivel[y];
  int j = 0;

  while(dif) {
    if(dif % 2 != 0) {
      x = t[x][j];
    }

    ++j;
    dif /= 2;
  }

  if(x == y) {
    return x;
  }

  int pas = log[nivel[x]];
  while(pas) {
    if(t[x][pas] != t[y][pas]) {
      x = t[x][pas];
      y = t[y][pas];
    }
    --pas;
  }

  if(t[x][pas] != t[y][pas]) {
    x = t[x][pas];
    y = t[y][pas];
  }

  return t[x][0];
}

void dfs(int node) {
  if(node != 1) {
    nivel[node] = 1 + nivel[tata[node]];
  }

  for(vector <int> :: iterator it = v[node].begin() ; it != v[node].end() ; ++it) {
    dfs(*it);
  }
}