Cod sursa(job #2354308)

Utilizator Radu_FilipescuFilipescu Radu Radu_Filipescu Data 25 februarie 2019 09:51:55
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
#include <fstream>
#include <vector>

using namespace std;

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

const int NMAX = 100003;
const int K = 20;

int N, nr_q;
vector <int> Ad[NMAX];

int lg[2 * NMAX];
int rmq[K][2 * NMAX];
int pos[NMAX];

int euler[2 * NMAX];
int lvl[2 * NMAX];
int last;

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

  int x;

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

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

void DFS( int nod, int depth )
{
  int w;

  euler[ ++last] = nod;
  lvl[last] = depth;

  if( pos[nod] == 0 ) pos[nod] = last;

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

    DFS( w, depth + 1 );

    euler[ ++last ] = nod;
    lvl[ last ] = depth;
  }
}

void Do()
{
  DFS( 1, 1 );

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

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

  int x, y;

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

     if( lvl[ pos[x] ] < lvl[ pos[y] ] ) rmq[j][i] = x;
     else rmq[j][i] = y;
   }

  int log2, ans;

  for( int i = 1; i <= nr_q; ++i )
  {
    fin >> x >> y;

    x = pos[x]; y = pos[y];

    if( x > y ) swap( x, y );

    log2 = lg[y - x + 1];

    ans = rmq[log2][x];

    int dif = y - ( 1 << log2 ) + 1;

    if( lvl[ pos[ans] ] > lvl[ pos[ rmq[log2][dif] ] ] )
      ans = rmq[log2][dif];

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

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

    return 0;
}