Cod sursa(job #2530227)

Utilizator nicolaee2Martinescu Nicolae nicolaee2 Data 24 ianuarie 2020 15:48:59
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.03 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

int rmq[20][NMAX<<2];
int lg[NMAX<<1];
int ap[NMAX<<1];
bool viz[NMAX<<1];
int h[NMAX<<1];
int euler[NMAX<<1];
int k;

vector<int> ma[NMAX];

int n,m;

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

    }
}


void afisare_rmq()
{
   for(int i=1;(1<<i)<=k;i++)
   {
      for(int j=1;j<=k-(1<<i)+1;j++)
      {
         cout<<rmq[i][j]<<" ";
      }
      cout<<endl;
   }
}

void formare_rmq()
{
   lg[0] = 0;
   lg[1] = 0;

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

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

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

}

void query_rmq()
{

   for(int i=1;i<=m;i++)
   {
      int x,y;
      fin>>x>>y;
      x = ap[x];
      y = ap[y];

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

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

      int sol = rmq[l][x];

      if(sol > rmq[l][y-(1<<l)+1])
         sol= rmq[l][y-(1<<l)+1];

      fout<<euler[sol]<<endl;;

   }
}

void DFS(int n,int niv)
{
   ++k;
   euler[k] = n;
   h[k] = niv;
   viz[n] = true;
   if(!ap[n])
      ap[n] = k;


   for(int i=0;i<ma[n].size();i++)
   {
      if(!viz[ma[n][i]])
      {
         DFS(ma[n][i],niv+1);
         euler[++k] = n;
         h[k] = niv;
      }
   }

}

int main()
{
   citire();
   DFS(1,0);

   //for(int i=1;i<=k;i++)
      //cout<<euler[i]<<" ";
   //cout<<endl;
   //for(int i=1;i<=k;i++)
      //cout<<h[i]<<" ";


   formare_rmq();
   //afisare_rmq();
   //formare_rmq();
   query_rmq();



}