Cod sursa(job #1147890)

Utilizator thebest001Neagu Rares Florian thebest001 Data 20 martie 2014 11:08:24
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.47 kb
#include <fstream>
#include <vector>
using namespace std;

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

#define MAX 100001

vector<int> graf[MAX + 1]; //reprezentarea arborelui de tati

int n, k;

int E[2 * MAX];//eulerian stuff
int N[2 * MAX]; //nivelul in ciclul eulerian
int ne; //numarul de elemente in parcurgerea euler

int F[MAX]; // prima aparitie in ciclul eulerian

int R[2 * MAX][20]; //rmq
int L[2 * MAX]; //logaritmul :)

void dfs(int x, int nivel) {
  E[++ne] = x;
  F[x] = ne;
  N[ne] = nivel;
  for (vector<int>::iterator i = graf[x].begin(); i != graf[x].end(); i++) {
    dfs(*i, nivel + 1);
    E[++ne] = x;
    N[ne] = nivel;
  }
}

void rmq() {
  int c = 0, p = 1;
  for (int i = 1; i <= ne; i++) {
    while (p * 2 <= i) {++c; p *= 2;}
    L[i] = c;
    R[i][0] = i;
  }
  for (int i = 1; i <= ne; i++)
    for (int j = 1; (1<<j) <= i;j++) {
      int a = R[i - (1<<(j - 1))][j - 1];
      int b = R[i][j - 1];
      if (N[a] > N[b])
        R[i][j] = b;
      else
        R[i][j] = a;
    }
}

int lca(int x, int y) {
  int a = F[x];
  int b = F[y];
  if (a > b){
    int aux = a;
    a = b;
    b = aux;
  }
  int p = L[b - a + 1];
  int A = R[a + (1<<p) - 1][p];
  int B = R[b][p];
  if (N[A] > N[B])
    return E[B];
  return E[A];
}


int main() {

  in>>n>>k;

  for (int i = 2; i <= n; i++) {
    int x;
    in>>x;
    graf[x].push_back(i);
  }

  dfs(1, 0);

  rmq();

  for (int i = 1; i <= k; i++) {
    int x, y;
    in>>x>>y;
    out<<lca(x, y)<<"\n";
  }

  return 0;
}