Cod sursa(job #2538807)

Utilizator isav_costinVlad Costin Andrei isav_costin Data 5 februarie 2020 10:17:13
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.25 kb
#include <fstream>
#include <vector>

#define pb push_back

const int MAXN = 100000;

using namespace std;

ifstream cin( "lca.in" );
ofstream cout( "lca.out" );

int n, m, q;

vector<int> fii[MAXN+1];

struct Node
{
  int nod, nivel;
};

vector<Node> euler;

int first[MAXN+1];
int log2[3*MAXN+1];
Node rmq[3*MAXN+1][20];

void parcurgereEuler( int sursa, int lvl )
{
  euler.pb({sursa,lvl});
  first[sursa]=euler.size();

  for( auto it:fii[sursa] )
  {
    parcurgereEuler(it,lvl+1);
    euler.pb({sursa,lvl});
  }
}

Node minim( Node a, Node b )
{
  if( b.nivel<a.nivel )
    a=b;

  return a;
}

int main()
{
  cin>>n>>q;

  for( int i=2;i<=n;i++ )
  {
    int k; cin>>k;

    fii[k].pb(i);
  }

  parcurgereEuler(1,0);

  m=euler.size();

  rmq[1][0]=euler[0];

  for( int i=2;i<=m;i++ )
  {
    log2[i]=log2[i/2]+1;
    rmq[i][0]=euler[i-1];
  }

  for( int j=1;(1<<j)<=m;j++ )
    for( int i=1;i<=m-(1<<j)+1;i++ )
    {
      int l=(1<<(j-1));

      rmq[i][j]=minim(rmq[i][j-1],rmq[i+l][j-1]);
    }

  while( q-- )
  {
    int x, y; cin>>x>>y;

    x=first[x];
    y=first[y];

    int l=log2[y-x+1];

    cout<<minim(rmq[x][l],rmq[y-(1<<l)+1][l]).nod<<"\n";
  }

  return 0;
}