Cod sursa(job #2375583)

Utilizator GoogalAbabei Daniel Googal Data 8 martie 2019 10:51:27
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.43 kb
#include <iostream>
#include <fstream>
#include <climits>
#include <vector>

using namespace std;

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

const int NMAX = 1e5;
const int LOGMAX = 18;

int n, m , c;

int poz[1 + 2 * NMAX];
int depth[1 + 2 * NMAX];

int vec[1 + 2 * NMAX];
int dp[1 + 3 * NMAX][1 + LOGMAX];

vector < int > g[1 + NMAX];

void dfs(int i, int d){
  int j = 0;
  int sz = g[i].size();
  while(j < sz){
    dfs(g[i][j], d + 1);
    poz[++c] = i;
    vec[i] = c;
    depth[c] = d;
    j++;
  }

  poz[++c] = i;
  vec[i] = c;
  depth[c] = d;
}

void rmq(){
  for(int i = 0; i <= 3 * NMAX; i++){
    for(int j = 0; j <= LOGMAX; j++){
      dp[i][j] = INT_MAX;
    }
  }

  for(int i = 1; i <= c; i++){
    dp[i][0] = poz[i];
  }

  for(int j = 1; (1 << j) <= c; j++){
    for(int i = 1; i <= c; i++){
      dp[i][j] = min(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
    }
  }
}

void dca(){
  for(int i = 1; i <= m; i++){
    int x, y, delta;
    in >> x >> y;
    x = vec[x];
    y = vec[y];
    if(y < x)
      swap(x, y);
    delta = y - x;
    if(delta == 0) {
      out << dp[x][0] << '\n';
    } else {
      int k = 0;
      for(k; (1 << k) <= delta; k++);
      k--;
      out << min(dp[x][k], dp[y - (1 << k) + 1][k]) << '\n';
    }
  }
}

int main()
{
  in >> n >> m;

  for(int i = 2; i <= n; i++) {
    int x;

    in >> x;
    g[x].push_back(i);
  }

  dfs(1, 1);

  rmq();
  dca();

  in.close();
  out.close();

  return 0;
}