Cod sursa(job #2598858)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 11 aprilie 2020 13:30:37
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.33 kb
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;
int DP[17][100005], depth[100005];
vector<int> Graph[100005];

void calculateDepth(int k, int d)
{
  depth[k] = d;
  for (auto v: Graph[k])
    calculateDepth(v, d + 1);
}

int nthAncestor(int k, int n)
{
  for (int i = 0; i <= 16 && n; ++i)
    if (n & (1<<i)) {
      n ^= (1<<i);
      k = DP[i][k];
    }
  
  return k;
}

int main()
{
  ifstream fin("lca.in");
  ofstream fout("lca.out");
  ios::sync_with_stdio(false);
  fin.tie(0);
  fout.tie(0);

  int N, M;

  fin >> N >> M;
  for (int i = 2; i <= N; ++i) {
    int x;
    fin >> x;
    Graph[x].emplace_back(i);
    DP[0][i] = x; // 2^0th ancestor of i is x
  }
  DP[0][1] = 1;
  
  for (int i = 1; i <= 16; ++i)
    for (int j = 1; j <= N; ++j) // 2^i th ancestor of j is the 2^(i-1)th ancestor of the 2^(i-1)th ancestor of j
      DP[i][j] = DP[i-1][DP[i-1][j]];
  
  
  calculateDepth(1, 0);

  for (int i = 1; i <= M; ++i) {
    int a, b;
    fin >> a >> b;
    if (depth[a] < depth[b])
      swap(a, b);
    int difference = depth[a] - depth[b];
    a = nthAncestor(a, difference);
    if (a == b) {
      fout << a << "\n";
      continue;
    }
    for (int k = 16; k >= 0; --k)
      if (DP[k][a] != DP[k][b]) {
	a = DP[k][a];
	b = DP[k][b];
      }
    fout << DP[0][a] << "\n";
  }
  
}