Cod sursa(job #2290769)

Utilizator ApostolIlieDanielApostol Daniel ApostolIlieDaniel Data 26 noiembrie 2018 22:46:48
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.3 kb
#include <bits/stdc++.h>

using namespace std;

FILE *fin = fopen ("lca.in", "r"), *fout = fopen ("lca.out", "w");

int euler;

const int MAXN = 1e5, MAXK = 20;

int a[MAXN * 2 + 1], rmq[MAXN * 2][MAXK];
int apar[MAXN + 1];
int lg[2 * MAXN + 1];
vector <int> gr[MAXN + 1];

void dfs (int nod, int tata) {
  a[++euler] = nod;
  apar[nod] = euler;
  for (auto fiu : gr[nod]) {
    if (fiu != tata) {
      dfs (fiu, nod);
      a[++euler] = nod;
    }
  }
}

void make_rmq () {
  int i, k;
  for (i = 1; i <= euler; i++)
    rmq[i][0] = a[i];
  for (i = 2; i <= euler; i++)
    lg[i] = lg[i / 2] + 1;
  for (k = 1; (1 << k) <= euler; k++) {
    for (i = 1; i <= euler; i++) {
      rmq[i][k] = min (rmq[i][k - 1], rmq[min (euler, i + (1 << (k - 1)))][k - 1]);
    }
  }
}

int query (int x, int y) {
  int l, r, k;
  l = apar[x];
  r = apar[y];
  if (l > r)
    swap (l, r);
  k = lg[r - l + 1];
  return min (rmq[l][k], rmq[r - (1 << k) + 1][k]);
}

int main() {
  int n, m, x, y, i;
  fscanf (fin, "%d%d", &n, &m);
  for (i = 2; i <= n; i++) {
    fscanf (fin, "%d", &x);
    gr[x].push_back (i);
    gr[i].push_back (x);
  }
  dfs (1, -1);
  make_rmq ();
  while (m--) {
    fscanf (fin, "%d%d", &x, &y);
    fprintf (fout, "%d\n", query (x, y));
  }
  return 0;
}