Cod sursa(job #1640166)

Utilizator thewildnathNathan Wildenberg thewildnath Data 8 martie 2016 16:12:09
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
#include <cstdio>
#include <vector>

using namespace std;

const int NMAX = 100000;
const int LGMAX = 17;

int n, m;

int t[1 + NMAX];
vector <int> v[1 + NMAX];

int eul;
int d[2 * NMAX];
int h[2 * NMAX];
int prim[1 + NMAX];

int lg[2 * NMAX];
int rmq[1 + LGMAX][1 + 2 * NMAX];

void dfs(int nod, int niv) {
  ++eul;
  d[eul] = nod;
  h[eul] = niv;
  prim[nod] = eul;

  for (int i = 0; i < v[nod].size(); ++i) {
    dfs(v[nod][i], niv + 1);
    ++eul;
    d[eul] = nod;
    h[eul] = niv;
  }
}

void calc() {
  dfs(1, 1);

  for (int i = 2; i <= eul; ++i)
    lg[i] = lg[i >> 1] + 1;

  for (int j = 1; j <= eul; ++j)
    rmq[0][j] = j;
  for (int i = 1; (1 << i) <= eul; ++i) {
      for (int j = 1; j + (1 << i) <= eul; ++j) {
      int lung = 1 << (i - 1);
      if (h[rmq[i - 1][j]] < h[rmq[i - 1][j + lung]])
        rmq[i][j] = rmq[i - 1][j];
      else
        rmq[i][j] = rmq[i - 1][j + lung];
    }
  }
}

int lca(int x, int y) {
  x = prim[x];
  y = prim[y];

  if (x > y) {
    int aux = x;
    x = y;
    y = aux;
  }

  int l = lg[y - x + 1];
  if (h[rmq[l][x]] < h[rmq[l][y - (1 << l) + 1]])
    return d[rmq[l][x]];
  else
    return d[rmq[l][y - (1 << l) + 1]];
}

int main() {
  freopen("lca.in", "r", stdin);
  freopen("lca.out", "w", stdout);

  scanf("%d%d", &n, &m);
  for (int i = 2; i <= n; ++i) {
    scanf("%d", &t[i]);
    v[t[i]].push_back(i);
  }

  calc();

  int x, y;
  while(m--) {
    scanf("%d%d", &x, &y);
    printf("%d\n", lca(x, y));
  }

  return 0;
}