Cod sursa(job #3225766)

Utilizator Radu_VasileRadu Vasile Radu_Vasile Data 18 aprilie 2024 19:29:19
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.44 kb
#include <bits/stdc++.h>
#define MAXN 100000
#define MAXLOG 18
using namespace std;
struct item{
  int node, level;
}rmq[MAXLOG][MAXN * 2];
int pcurent;
int pstart[2 * MAXN];
int e[2 * MAXN];
vector<int> v[MAXN + 1];
void dfs(int node, int level){
  rmq[0][++pcurent] = {node, level};
  pstart[node] = pcurent;
  for(auto &i : v[node]){
    dfs(i, level + 1);
    rmq[0][++pcurent] = {node, level};
  }
}
void precompute(){
  int i, p;
  for( p = 1; (1 << p) <= pcurent; p++ ){
    for( i = 1; i + (1 << p) - 1 <= pcurent; i++){
      item st = rmq[p - 1][i];
      item dr = rmq[p - 1][i + (1 << (p - 1))];
      rmq[p][i] = st.level < dr.level ? st : dr;
    }
  }
  for( i = 2; i <= pcurent; i++ ){
    e[i] = e[i / 2] + 1;
  }
}
int lca(int x, int y){
  x = pstart[x];
  y = pstart[y];
  if(x > y)
    swap(x, y);
  int p = e[y - x + 1];
  item st = rmq[p][x];
  item dr = rmq[p][y - (1 << p) + 1];
  if(st.level < dr.level)
    return st.node;
  return dr.node;
}
int main(){
  FILE *fin, *fout;
  int n, m, x, y, i;
  fin = fopen( "lca.in", "r" );

  fscanf(fin, "%d%d", &n, &m);
  for( i = 2; i <= n; i++ ){
    fscanf(fin, "%d", &x);
    v[x].push_back(i);
  }

  fout = fopen( "lca.out", "w" );

  pcurent = 0;
  dfs(1, 1);
  precompute();

  for( i = 0; i < m; i++  ){
    fscanf(fin, "%d%d", &x, &y);
    fprintf(fout, "%d\n", lca(x, y));
  }

  fclose( fin );
  fclose( fout );
  return 0;
}