Cod sursa(job #3177224)

Utilizator PescarusTanislav Luca Andrei Pescarus Data 28 noiembrie 2023 19:02:30
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.53 kb
//solutie cu rmq

#include <fstream>
#include <vector>

using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");

const int nmax = 100005;
vector<int> l[nmax];
struct rmq{
  int node, lvl;
}dp[19][2 * nmax];
int euler[2 * nmax], cnt, poz[2 * nmax], Log2[2 * nmax];
int n, m;

void dfs(int nod, int niv){
  dp[0][++cnt] = {nod, niv};
  poz[nod] = cnt;
  for(auto vec: l[nod]){
    dfs(vec, niv + 1);
    dp[0][++cnt] = {nod, niv};
  }
}
void rangeminquery(){
  for(int p = 1; p < 19; p++){
      for(int i = 1; i <= cnt; i++){
        rmq st = dp[p - 1][i];
        if(i + (1 << (p - 1)) <= cnt){
          rmq dr = dp[p - 1][i + (1 << (p - 1))];
          if(st.lvl < dr.lvl){
            dp[p][i] = st;
          }
          else{
            dp[p][i] = dr;
          }
        }
        else{
          dp[p][i] = st;
        }
      }
  }
}

int lca(int a, int b){
  int poz_a = poz[a];
  int poz_b = poz[b];
  if(poz_a > poz_b){
    swap(poz_a, poz_b);
  }
  int p = Log2[poz_b - poz_a + 1];
  rmq st = dp[p][poz_a];
  rmq dr = dp[p][poz_b - (1 << p) + 1];
  if(st.lvl < dr.lvl){
    return st.node;
  }
  else{
    return dr.node;
  }


}

int main(){
  f >> n >> m;
  for(int i = 2; i <= n; i++){
    int x;
    f >> x;
    l[x].push_back(i);
  }
  cnt = 0;
  dfs(1, 1);
  rangeminquery();
  Log2[1] = 0;
  for(int i = 2; i <= cnt; i++){
    Log2[i] = Log2[i / 2] + 1;
  }
  while(m--){
    int x, y;
    f >> x >> y;
    g << lca(x, y) << '\n';
  }
  return 0;
}