Cod sursa(job #2741057)

Utilizator euyoTukanul euyo Data 15 aprilie 2021 13:58:23
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.66 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream fin( "lca.in" );
ofstream fout( "lca.out" );

const int MaxN = 100003;
const int MaxLog = 20;

vector<int> tree[MaxN];
vector<int> euler;
vector<int> level;
int viz[MaxN], pos[MaxN], lg[2 * MaxN];
struct { int val, pos; } minr[MaxLog][2 * MaxN];

void buildEuler( int node, int dep ) {
  viz[node] = 1;
  euler.push_back( node );
  level.push_back( dep );
  for ( int i = 0; i < tree[node].size(); ++i ) {
    if ( !viz[tree[node][i]] ) {
	  buildEuler( tree[node][i], dep + 1 );
	}
	euler.push_back( node );
	level.push_back( dep );
  }
}

int LCA( int x, int y ) {
  int l = min( pos[x], pos[y] ), r = max( pos[x], pos[y] );
  int k = lg[r - l + 1];
  
  if ( minr[k][l].val > minr[k][r - (1 << k) + 1].val ) {
    return euler[minr[k][l].pos];
  } 
  return euler[minr[k][r - (1 << k) + 1].pos];
}

int main() {
  int n, k, f, u, v;

  fin >> n >> k;
  for ( int i = 2; i <= n; ++i ) {
    fin >> f;
	tree[f].push_back( i );
  }
  buildEuler( 1, 0 );
  for ( int i = 0; i < euler.size(); ++i ) {
    if ( !pos[euler[i]] ) {
      pos[euler[i]] = i;
	}
  }
  n = euler.size();
  for ( int i = 2; i <= n; ++i ) {
	lg[i] = lg[i >> 1] + 1;
  }
  for ( int i = 0; i < n; ++i ) {
	minr[0][i].val = level[i];
    minr[0][i].pos = i;
  }
  for ( int i = 1; i <= lg[n]; ++i ) {
	for ( int j = 0; j + (1 << (i - 1)) < n; ++j ) {
      if ( minr[i - 1][j].val > minr[i - 1][j + (1 << (i - 1))].val ) {
        minr[i][j] = minr[i - 1][j + (1 << (i - 1))];
	  } else {
        minr[i][j] = minr[i - 1][j];
	  }
	}
  }
  while ( k-- ) {
	fin >> u >> v;
    fout << LCA( u, v ) << "\n";  
  }
  fin.close(); 
  fout.close();
  return 0;
}