Cod sursa(job #2005626)

Utilizator mouse_wirelessMouse Wireless mouse_wireless Data 27 iulie 2017 17:31:53
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
#include <cassert>
#include <cstring>
#include <climits>
#include <unordered_map>
using namespace std;
typedef long long LL;

#ifdef INFOARENA
#define ProblemName "lca"
#endif

#define MCONCAT(A, B) A B
#ifdef ProblemName
#define InFile MCONCAT(ProblemName, ".in")
#define OuFile MCONCAT(ProblemName, ".out")
#else
#define InFile "fis.in"
#define OuFile "fis.out"
#endif

const int MAXN = 100010;
const int MAXLOG = 18;

int H[MAXN];
int P[MAXN][MAXLOG];
vector<int> G[MAXN];

void dfs(int x, int p = -1) {
  if (p >= 0)
    H[x] = H[p] + 1;
  P[x][0] = p;
  for (int l = 0; l < MAXLOG; ++l) {
    if (P[x][l - 1] < 0)
      break;
    P[x][l] = P[P[x][l - 1]][l - 1];
  }
  for (const auto &y : G[x])
    dfs(y, x);
}

int lca(int x, int y) {
  if (H[x] < H[y])
    swap(x, y);
  for (int l = MAXLOG - 1; l >= 0 && H[x] > H[y]; --l)
  if (P[x][l] >= 0 && H[P[x][l]] >= H[y])
    x = P[x][l];
  if (x == y)
    return x;
  for (int l = MAXLOG - 1; l >= 0; --l)
  if (P[x][l] != P[y][l])
    x = P[x][l], y = P[y][l];
  return P[x][0];
}

int main() {
  assert(freopen(InFile, "r", stdin));
  assert(freopen(OuFile, "w", stdout));
  int N, Q;
  scanf("%d%d", &N, &Q);
  for (int i = 1; i < N; ++i) {
    int a;
    scanf("%d", &a);
    --a;
    G[a].push_back(i);
  }
  memset(P, 0xFF, sizeof(P));
  dfs(0);
  while (Q--) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a, --b;
    printf("%d\n", lca(a, b) + 1);
  }
  return 0;
}