Cod sursa(job #562172)

Utilizator dushmiMihai-Alexandru Dusmanu dushmi Data 22 martie 2011 15:43:23
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

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

const int N = 100005;

vector<int> L[N];

int e_lung, n, q, firstap[N], e_nod[4 * N], e_lvl[4 * N], rmq[4 * N][22];

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

void euler(int nod, int lvl) {
  ++ e_lung;
  firstap[nod] = e_lung;
  e_nod[e_lung] = nod;
  e_lvl[e_lung] = lvl;
  rmq[e_lung][0] = e_lung;
  for (vector<int> :: iterator it = L[nod].begin(); it != L[nod].end(); ++ it) {
    euler(*it, lvl + 1);
    ++ e_lung;
    e_nod[e_lung] = nod;
    e_lvl[e_lung] = lvl;
    rmq[e_lung][0] = e_lung;
  }
}

int minim(int x, int y) {
  return x < y ? x : y;
}

void make_rmq() {
  for (int j = 1; (1 << j) <= e_lung; ++ j)
    for (int i = 1; i + (1 << j) <= e_lung; ++ i)
      if (e_lvl[rmq[i][j - 1]] < e_lvl[rmq[i + (1 << (j - 1))][j - 1]])
        rmq[i][j] = rmq[i][j - 1];
      else
        rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
}

int lca(int x, int y) {
  int p2 = 0;
  while ((1 << (p2 + 1)) <= y - x)
    ++ p2;
  if(e_lvl[rmq[x][p2]] <  e_lvl[rmq[y - (1 << p2) + 1][p2]])
    return rmq[x][p2];
  return rmq[y - (1 << p2) + 1][p2];
}

void solve() {
  int x, y;
  for (int i = 1; i <= q; ++ i) {
    in >> x >> y;
    if (firstap[x] > firstap[y])
      swap(x,y);
    out << e_nod[lca(firstap[x], firstap[y])] << '\n';     
  }
}

int main() {
  read();
  euler(1, 0);
  make_rmq();
  solve();
  return 0;
}