Cod sursa(job #562175)

Utilizator dushmiMihai-Alexandru Dusmanu dushmi Data 22 martie 2011 15:46:41
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.57 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, p2[22], 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() {
  p2[0] = 1;
  for (int i = 1; i <= 21; ++ i)
    p2[i] = (p2[i - 1] << 1);
  for (int j = 1; p2[j] <= e_lung; ++ j)
    for (int i = 1; i + p2[j] <= e_lung; ++ i)
      if (e_lvl[rmq[i][j - 1]] < e_lvl[rmq[i + p2[j - 1]][j - 1]])
        rmq[i][j] = rmq[i][j - 1];
      else
        rmq[i][j] = rmq[i + p2[j - 1]][j - 1];
}

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

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;
}