Cod sursa(job #2093489)

Utilizator Stefan_RaduStefan Radu Stefan_Radu Data 23 decembrie 2017 20:17:25
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.87 kb
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;

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

const int INF = 1e9;

void Dfs(int cur_node, int cur_level, int &index, vector < int > &euler, 
    vector < vector < int > > &gr, vector < int > &first_ap, vector < int > &level) {
  
  level[cur_node] = cur_level;
  euler[++ index] = cur_node;
  if (not first_ap[cur_node]) {
    first_ap[cur_node] = index;
  }

  for (auto x : gr[cur_node]) {
    Dfs(x, cur_level + 1, index, euler, gr, first_ap, level);
    euler[++ index] = cur_node;
  }
}

int main() {

  int n, m;
  cin >> n >> m; 

  vector < int > tata(n + 1);
  vector < vector < int > > gr(n + 1);

  for (int i = 2; i <= n; i ++) {
    cin >> tata[i];
    gr[tata[i]].push_back(i);
  }
  
  int index = 0;
  vector < int > level(n + 1);
  vector < int > first_ap(n + 1);
  vector < int > euler(1e6 + 7);
  Dfs(1, 1, index, euler, gr, first_ap, level);

  vector < int > log_2(1e6 + 7);
  log_2[1] = 0;
  for (int i = 2; i < (int) log_2.size(); i ++) {
    log_2[i] = log_2[i / 2] + 1; 
  }
  
  int lim = log_2[index + 1];
  vector < vector < int > > dp(lim + 1, vector < int > (index + 1));
  for (int i = 1; i <= index; i ++) {
    dp[0][i] = euler[i];
  }

  for (int i = 1; i <= lim; i ++) {
    for (int j = 1; j <= index; j ++) {
      
      int l = dp[i - 1][j];
      int k = j + (1 << (i - 1));
      if (k <= index) {
        int r = dp[i - 1][k];
        if (level[r] < level[l]) {
          l = r;
        }
      }
      dp[i][j] = l;
    }
  }

  int x, y;
  for (int i = 1; i <= m; i ++) {
    
    cin >> x >> y;
    x = first_ap[x];
    y = first_ap[y];
    if (x > y) {
      swap(x, y);
    }
    
    int k = log_2[y - x + 1];
    int l = dp[k][x];
    int r = dp[k][y - (1 << k) + 1];
    if (level[l] <= level[r]) {
      cout << l << '\n';
    }
    else {
      cout << r << '\n';
    }
  }
}