Cod sursa(job #2093004)

Utilizator Stefan_RaduStefan Radu Stefan_Radu Data 22 decembrie 2017 19:10:14
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.63 kb
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;

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

const int MAX = 1e5 + 7;
vector < int > tata(MAX);
vector < int > level(MAX);
vector < vector < int > > chain(MAX);
vector < int > chain_of(MAX);
vector < vector < int > > gr(MAX);

void Dfs(int cur_node, int cur_level, int &chain_nr, int &lim) {
  
  level[cur_node] = cur_level;
  if (gr[cur_node].size() == 0) {
    chain[++ chain_nr].push_back(cur_node);
    chain_of[cur_node] = chain_nr;
    return;
  }
  
  bool found_not_full = false;
  for (auto x : gr[cur_node]) {
    Dfs(x, cur_level + 1, chain_nr, lim);
    if (not found_not_full) {
      if ((int) chain[chain_of[x]].size() < lim) {
        found_not_full = true;
        chain[chain_of[x]].push_back(cur_node);
        chain_of[cur_node] = chain_of[x];
      }
    }
  }

  if (not found_not_full) {
    chain[++ chain_nr].push_back(cur_node);
    chain_of[cur_node] = chain_nr;
  }
}

void Move(int &k) {

  int t = chain[chain_of[k]].back();
  k = tata[t];
}

bool is_top(int k) {

  return chain[chain_of[k]].back() == 1;
}

int main() {

  int n, m;
  cin >> n >> m;
  
  for (int i = 2; i <= n; i ++) {
    cin >> tata[i];
    gr[tata[i]].push_back(i);
  }

  int lim = sqrt(n);
  int max_chain = 0;
  Dfs(1, 1, max_chain, lim);
  
  int x, y;
  for (int i = 1; i <= m; i ++) {
    cin >> x >> y;

    while(chain_of[x] != chain_of[y]) {

      if (level[x] >= level[y] and (not is_top(x))) {
        Move(x);
      }
      else {
        Move(y);
      }
    }

    if (level[x] <= level[y]) {
      cout << x << '\n';
    }
    else {
      cout << y << '\n';
    }
  }
}