Cod sursa(job #756095)

Utilizator XladhenianGrigorita Vlad-Stefan Xladhenian Data 8 iunie 2012 23:59:58
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.93 kb
                                                     
#include <fstream>
#include <vector>
using namespace std;

long N;
long CL;
long A[300005];
long App[300005];
long E[300005];
long Data[22][300005];
long lg[300005];

long minint(long a,long b)
{
 if (a < b)
   {
    return a;
   }
 return b;
}

void Build(void)
{
 long l,i;
 lg[1] = 0;
 for (i = 2;i <= N;i += 1)
  {
   lg[i] = lg[i >> 1] + 1;
  }
 for (i = 0;i < N;i += 1)
  {
   Data[0][i] = i;
  }
 for (l = 1;(1 << l) <= N;l += 1)
  {
   for (i = 0;i < N - (1 << (l - 1));i += 1)
    {
     if (A[Data[l - 1][i]] < A[Data[l - 1][i + (1 << (l - 1))]])
       {
        Data[l][i] = Data[l - 1][i];
       }
      else
       {
        Data[l][i] = Data[l - 1][i + (1 << (l - 1))];
       }
    }
  }
}

long Compute(long x,long y)
{
 long l = lg[y - x];
 if (A[Data[l][x]] < A[Data[l][y - (1 << l) + 1]])
   {
    return E[Data[l][x]];
   }
  else
   {
    return E[Data[l][y - (1 << l) + 1]];
   }
}

vector<int> *Fii;

void RSRDR(long nod,long nivel)
{
 long i;
 if (App[nod] == 0)
   {
    App[nod] = CL;
   }
 A[CL] = nivel;
 E[CL] = nod;
 CL += 1;
 for (i = 0;i < Fii[nod].size();i += 1)
  {
   RSRDR(Fii[nod][i],nivel + 1);
   A[CL] = nivel;
   E[CL] = nod;
   CL += 1;
  }
}

void BuildInput(fstream &fin)
{
 Fii = new vector<int>[N];
 long i,x;
 for (i = 1;i < N;i += 1)
  {
   fin >> x;
   Fii[x].push_back(i + 1);
  }
 CL = 0;
 RSRDR(1,0);
 N = CL;
}

int main(void)
{
 long M,i,x,y,z;
 fstream fin("lca.in",ios::in);
 fstream fout("lca.out",ios::out);
 fin >> N >> M;
 BuildInput(fin);
 Build();
 for (i = 0;i < M;i += 1)
  {
   fin >> x >> y;
   if (x == y)
     {
      fout << x << "\n";
      continue;
     }
   if (App[x] > App[y])
     {
      z = x;
      x = y;
      y = z;
     }
   fout << Compute(App[x],App[y]) << "\n";
  }
 fin.close();
 fout.close();
 return 0;
}