Cod sursa(job #2530282)

Utilizator nicolaee2Martinescu Nicolae nicolaee2 Data 24 ianuarie 2020 16:43:33
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.91 kb
#include <iostream>
#include <fstream>
#include<bits/stdc++.h>

using namespace std;

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

#define NMAX 100005
#define MOD 1000000000

vector<int> GR[NMAX];
int n,m;
int h[NMAX<<1];
int euler[NMAX<<1];
int lg[NMAX<<1];
int k;
int prim[NMAX<<1];
int rmq[20][NMAX<<2];

void citire()
{
   fin>>n>>m;
   for(int i=2;i<=n;i++)
   {
      int x;
      fin>>x;
      GR[x].push_back(i);
   }
}

void DFS(int nod,int niv)
{
   euler[++k] = nod;
   h[k] = niv;
   prim[nod] = k;

   for(int i=0;i<GR[nod].size();i++)
   {
      DFS(GR[nod][i],niv+1);
      euler[++k] = nod;
      h[k] = niv;
   }

}


void rmq_form()
{
   for(int i=1;i<=k;i++)
      rmq[0][i] = i;

   for(int i=2;i<=k;i++)
      lg[i] = lg[i>>1]+1;

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

         rmq[i][j] = rmq[i-1][j];
         if(h[rmq[i-1][j+(1<<(i-1))]] < h[rmq[i-1][j]])
         {
            rmq[i][j]  = rmq[i-1][j+(1<<(i-1))];
         }

      }
   }
}

int lca(int a,int b)
{
   int x,y;
   x = prim[a];
   y = prim[b];
   if(x>y)
      swap(x,y);
   int diff = y-x+1;
   int l = lg[diff];

   int sol = rmq[l][x];
   if(h[sol] > h[rmq[l][y-(1<<l)+1]])
   {
      sol = rmq[l][y-(1<<l)+1];
   }
   return euler[sol];


}

void afisare()
{

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

         cout<<rmq[i][j]<<" ";

      }
      cout<<endl;
   }
}

int main()
{
   citire();

   //for(int i=1;i<=n;i++)
   //{
      //for(int j=0;j<GR[i].size();j++)
         //cout<<GR[i][j]<<" ";
      //cout<<endl;
   //}

   DFS(1,0);

   rmq_form();

   //afisare();

   for(int i=1;i<=m;i++)
   {
      int a,b;
      fin>>a>>b;
      //cout<<a<<" "<<b<<endl;;
      fout<<lca(a,b)<<'\n';
   }

}