Cod sursa(job #2374469)

Utilizator AlexTudorAlex Brinza AlexTudor Data 7 martie 2019 18:54:22
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.03 kb
#include <fstream>
#include <vector>

using namespace std;

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

const int NMAX = 100005;

int N, nr_q;

vector <int> Ad[NMAX];

int pos[NMAX];
int h[NMAX];
int euler[2 * NMAX];
int last;

int rmq[20][2*NMAX];
int lg[2*NMAX];

void Read()
{
  fin >> N >> nr_q;

  int val;
  for( int i = 2; i <= N; ++i )
   {
     fin >> val;

     Ad[val].push_back( i );
     Ad[i].push_back( val );
   }
}

void Dfs( int nod, int parent, int height )
{
  int w;

  euler[ ++last] = nod;

  if( pos[nod] == 0 )
  {
    pos[nod] = last;
    h[nod] = height;
  }

  for( int i = 0; i < Ad[nod].size(); ++i )
  {
    w = Ad[nod][i];

    if( w == parent ) continue;

    Dfs( w, nod, height + 1 );

    euler[++last] = nod;
  }
}

void Do()
{
  Dfs( 1, 0, 1 );

  for( int i = 1; i <= last; ++i )
    rmq[0][i] = euler[i];

  int a, b;

  lg[2] = 1;
  for( int i = 3; i <= N; ++i )
    lg[i] = lg[i / 2] + 1;

  for( int i = 1; ( 1 << i ) <= last; ++i )
  {
    for( int j = 1; j + ( 1 << i ) + 1 <= last; ++j )
    {
      a = rmq[i - 1][j];
      b = rmq[i - 1][j + ( 1 << ( i - 1 ) ) - 1];

      if( h[a] < h[b] ) rmq[i][j] = a;
      else rmq[i][j] = b;
    }
  }

  /*for( int i = 1; i <= last; ++i )
    fout << euler[i] << ' ';
{1}
  fout << '\n';
{1}
  for( int i = 1; i <= last; ++i )
    fout << h[euler[i]] << ' ';
{1}
  fout << '\n';
{1}
  for( int i = 1; ( 1 << i ) <= last; ++i )
  {
    for( int j = 1; j + ( 1 << i ) + 1 <= last; ++j )
    {
      fout << rmq[i][j] << ' ';
    }
{1}
    fout << '\n';
  }*/

  int logg, ans;

  for( int i = 1; i <= nr_q; ++i )
  {
    fin >> a >> b;

    a = pos[a];
    b = pos[b];

    if( a > b ) swap( a, b );

    logg = lg[b - a + 1];

    ans = rmq[logg][a];

    if( h[ rmq[logg][a] ] > h[ rmq[logg][b - ( 1 << logg ) + 1]] ) ans = rmq[logg][b - ( 1 << logg ) + 1];

    fout << ans << '\n';
  }

}

int main()
{
    Read();
    Do();

    return 0;
}