Cod sursa(job #2598926)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 11 aprilie 2020 13:38:34
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.35 kb
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;
int DP[17][100005], depth[100005], Log2[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 = Log2[n]; i >=0; --i)
    if (n & (1<<i))
      k = DP[i][k];
  
  return k;
}

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

  scanf("%d%d", &N, &M);
  Log2[1] = 0;
  for (int i = 2; i <= N; ++i) {
    int x;
    scanf("%d", &x);
    Graph[x].emplace_back(i);
    DP[0][i] = x; // 2^0th ancestor of i is x
    Log2[i] = Log2[i/2] + 1;
  }
  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;
    scanf("%d%d", &a, &b);
    if (depth[a] < depth[b])
      swap(a, b);
    int difference = depth[a] - depth[b];
    a = nthAncestor(a, difference);
    if (a == b) {
      printf("%d\n", a);
      continue;
    }
    for (int k = Log2[depth[a]]; k >= 0; --k)
      if (DP[k][a] != DP[k][b]) {
	a = DP[k][a];
	b = DP[k][b];
      }
    printf("%d\n", DP[0][a]);
  }
  
}