Cod sursa(job #2283984)

Utilizator PetyAlexandru Peticaru Pety Data 16 noiembrie 2018 12:35:07
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.38 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin ("lca.in");
ofstream fout ("lca.out");

int n, m, k;
int lg[400002];
int rmq[20][400002];
int lvl[400002], first[100002];
int euler[400002];
vector<int>G[100002];

void dfs (int nod, int l) {
  euler[++k] = nod;
  lvl[k] = l;
  first[nod] = k;
  for (int i = 0; i < G[nod].size(); i++) {
    dfs (G[nod][i], l + 1);
    euler[++k] = nod;
    lvl[k] = l;
  }
}

void Rmq () {
  for (int i = 1; i <= k; i++)
    rmq[0][i] = i;
  for (int i = 1; (1 << i) < k; i++)
    for (int j = 1; j <= k - (1 << i) + 1; j++) {
      int aux = 1 << (i - 1);
      if (lvl[rmq[i - 1][j + aux]] < lvl[rmq[i - 1][j]])
        rmq[i][j] = rmq[i - 1][j + aux];
      else
        rmq[i][j] = rmq[i - 1][j];
    }
  for (int i = 2; i <= k; i++)
    lg[i] = lg[i / 2] + 1;
}

int lca (int x, int y) {
  int st = first[x], dr = first[y];
  if (st > dr)
    swap(st, dr);
  int dist = dr - st + 1;
  int ans = rmq[lg[dist]][st];
  int aux = dist - (1 << lg[dist]);
  if (lvl[ans] > lvl[rmq[lg[dist]][st + aux]])
    ans = rmq[lg[dist]][st + aux];
  return euler[ans];
}


int main()
{
  fin >> n >> m;
  for (int i = 2; i <= n; i++) {
      int x;
    fin >> x;
    G[x].push_back(i);
  }
  dfs(1, 0);
  Rmq();
  while (m--) {
    int x, y;
    fin >> x >> y;
    fout << lca(x, y) << "\n";
  }
  return 0;
}