Cod sursa(job #2306698)

Utilizator vlad.ulmeanu30Ulmeanu Vlad vlad.ulmeanu30 Data 22 decembrie 2018 19:34:23
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.5 kb
#include <bits/stdc++.h>
#define maxn 100000
#define maxm 2000000
#define logn 17
#define pb push_back

using namespace std;

vector <int> g[maxn+5];
vector <int> eul;
vector <int> adc;
int loc[maxn+5];
bool fv[maxn+5];
int dp[logn+1][maxn+5];

int getl2 ( int n ) { return log ( n ) / log ( 2 ); }

int rmq ( int lo, int hi )
{
  if ( lo > hi ) swap ( lo, hi );
  int l = getl2 ( hi - lo + 1 );
  if ( adc[dp[l][lo]] < adc[dp[l][hi-(1<<l)+1]] )
    return dp[l][lo];
  return dp[l][hi-(1<<l)+1];
}

void dfs ( int nod, int nadc )
{
  if ( fv[nod] == 0 )
    fv[nod] = 1, loc[nod] = eul.size();

  int i, sz = g[nod].size();
  eul.pb ( nod ), adc.pb ( nadc );

  for ( i = 0; i < sz; i++ )
  {
    dfs ( g[nod][i], nadc + 1 );
    eul.pb ( nod ), adc.pb ( nadc );
  }
}

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

  int n, m;
  fin >> n >> m;

  int i, j, x;
  for ( i = 1; i < n; i++ )
  {
    fin >> x;
    g[x-1].push_back ( i );
  }

  dfs ( 0, 0 );

  int sz = eul.size(), l2 = getl2 ( sz );

  for ( j = 0; j < sz; j++ )
    dp[0][j] = j;

  for ( i = 1; i <= l2; i++ )
    for ( j = 0; j + (1<<i) <= sz; j++ )
      if ( adc[dp[i-1][j]] < adc[dp[i-1][j+(1<<(i-1))]] )
        dp[i][j] = dp[i-1][j];
      else dp[i][j] = dp[i-1][j+(1<<(i-1))];

  int a, b;
  for ( i = 0; i < m; i++ )
  {
    fin >> a >> b;
    fout << 1 + eul[rmq(loc[a-1], loc[b-1])] << '\n';
  }

  fin.close ();
  fout.close ();

  return 0;
}