Cod sursa(job #1640181)

Utilizator thewildnathNathan Wildenberg thewildnath Data 8 martie 2016 16:16:06
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.09 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]];
}

////
const int LBUFF = 500000;

char buff[LBUFF];
int pz = LBUFF - 1;

int getInt() {
  while (buff[pz] < '0' || buff[pz] > '9') {
    ++pz;
    if (pz == LBUFF) {
      pz = 0;
      fread(buff, 1, LBUFF, stdin);
    }
  }

  int num = 0;
  while (buff[pz] >= '0' && buff[pz] <= '9') {
    num = num * 10 + buff[pz] - '0';
    ++pz;
    if (pz == LBUFF) {
      pz = 0;
      fread(buff, 1, LBUFF, stdin);
    }
  }

  return num;
}
////

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

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

  calc();

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

  return 0;
}