Cod sursa(job #2346356)

Utilizator Radu_FilipescuFilipescu Radu Radu_Filipescu Data 17 februarie 2019 16:12:00
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.31 kb
#include <fstream>
#include <vector>

using namespace std;

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

const int NMAX = 100005;
const int INF = 20000000000;

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

vector <int> E;
vector <int> H;

int pos[NMAX];

int tree[4 * NMAX];

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

  int x, y;

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

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

void DFS_euler( int nod, int parent, int height )
{
  if( pos[nod] == 0 ) pos[nod] = E.size();

  E.push_back( nod );
  H.push_back( height );

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

    if( w == parent ) continue;

    DFS_euler( w, nod, height + 1 );

    E.push_back( nod );
    H.push_back( height );
  }
}

void Update( int nod, int lf, int rg, int poz, int val )
{
  if( lf == rg )
  {
    tree[nod] = E[lf];

    return;
  }

  int mid = ( lf + rg ) / 2;

  if( poz <= mid ) Update( nod * 2, lf, mid, poz, val );
  else Update( nod * 2 + 1, mid + 1, rg, poz, val );

  if( tree[nod * 2] > 0 && ( tree[nod] == 0 || H[ pos[ tree[nod * 2] ]] < H[ pos[ tree[nod] ] ] ) )
   tree[nod] = tree[nod * 2];

  if( tree[nod * 2 + 1] > 0 && ( tree[nod] == 0 || H[ pos[ tree[nod * 2 + 1] ] ] < H[ pos[ tree[nod] ] ] ) )
   tree[nod] = tree[nod * 2 + 1];

  //if( lf == 17 && rg == 18 )
  //  fout << H[ pos[tree[nod * 2]]] << ' ' << H[tree[nod * 2 + 1]] << ' ' << tree[nod] << '\n';
}

int Query( int nod, int lf, int rg, int L, int R )
{
  if( L <= lf && rg <= R ) return tree[nod];

  int mid = ( lf + rg ) / 2;

  int ans = INF;
  int ans2;

  if( L <= mid ) ans = Query( nod * 2, lf, mid, L, R );
  if( R > mid )
  {
    ans2 = Query( nod * 2 + 1, mid + 1, rg, L, R );

    if( ans == INF || H[pos[ans2]] < H[pos[ans]] ) ans = ans2;
  }

  return ans;
}

void Do()
{
  E.push_back( 0 );
  H.push_back( 0 );

  DFS_euler( 1, 0, 1 );

  int sz = E.size() - 1;

  for( int i = 1; i <= sz; ++i )
   Update( 1, 1, sz, i, E[i] );

  int x, y;

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

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

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

    fout << Query( 1, 1, sz, x, y ) << '\n';
  }
}

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

    return 0;
}