Cod sursa(job #1383732)

Utilizator robertstrecheStreche Robert robertstreche Data 10 martie 2015 16:24:18
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.37 kb
#include <cstdio>
#include <vector>
#include <cmath>

#define MAXLOG 20
#define NMAX 100005

using namespace std;

int n,nr,x,y,tata,query;
int mi[MAXLOG+1][2*NMAX];
int nivel[NMAX],poz[NMAX],vec[2*NMAX];

vector <int>v[NMAX];

inline void euler(int nod,int nivelc)
{
    nivel[nod]=nivelc;
    vec[++nr]=nod;
    poz[nod]=nr;

    for (vector <int>::iterator it=v[nod].begin();it!=v[nod].end();it++)
     {
         euler(*it,nivelc+1);
         vec[++nr]=nod;
     }
}
inline void rmq()
{
    for (int i=1;i<=nr;i++)
     mi[0][i]=i;
    for (int i=1;i<=MAXLOG;i++)
      for (int j=1;j+(1<<i-1)<=nr;j++)
        mi[i][j]=(nivel[vec[mi[i-1][j]]]<nivel[vec[mi[i-1][j+(1<<(i-1))]]]?mi[i-1][j]:mi[i-1][j+(1<<(i-1))]);
}
int main()
{
   freopen("lca.in","r",stdin);
   freopen("lca.out","w",stdout);

   scanf("%d %d",&n,&query);

   for (int i=2;i<=n;i++)
    {
       scanf("%d",&tata);
       v[tata].push_back(i);
    }
   euler(1,1);
   rmq();

   for (int i=1;i<=query;i++)
   {
       scanf("%d %d",&x,&y);
       int poz1=poz[x];
       int poz2=poz[y];
       if (poz1>poz2)swap(poz1,poz2);
       int len=log2(poz2-poz1+1);

       int lca=(nivel[vec[mi[len][poz1]]]<nivel[vec[mi[len][poz2-(1<<len)+1]]]?vec[mi[len][poz1]]:vec[mi[len][poz2-(1<<len)+1]]);

       printf("%d\n",lca);
   }

   fclose(stdin);
   fclose(stdout);

}