Cod sursa(job #2187479)

Utilizator NeredesinI am not real Neredesin Data 26 martie 2018 15:57:43
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.49 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 LGMAX = 18;

int n, m, c;
int pos[1 + 2 * NMAX];
int dep[1 + 2 * NMAX];
int v[1 + 2 * NMAX];
int dp[1 + 3 * NMAX][1 + LGMAX];
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);
    pos[++c] = i;
    v[i] = c;
    dep[c] = d;
    j++;
  }

  pos[++c] = i;
  v[i] = c;
  dep[c] = d;
}

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

  for(int i = 1; i <= c; i++){
    dp[i][0] = pos[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 = v[x];
    y = v[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;
}