Cod sursa(job #1519049)

Utilizator DrumeaVDrumea Vasile DrumeaV Data 6 noiembrie 2015 19:04:55
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.67 kb
#include <stdio.h>
#include <string.h>
#include <vector>
#include <algorithm>

const int MN = 100005;
const int ML = 20;

using namespace std;

int N,M,Cnt;
int P[ML];
int V[MN << 1],L[MN << 1],F[MN << 1],Lg[MN << 1];
int RMQ[MN << 1][ML];
vector< int > G[MN];

void DFS(int Vert,int Level)
{
    V[++Cnt] = Vert;
    L[Cnt] = Level;
    F[Vert] = Cnt;

    int Sz = G[Vert].size();

    for (int i = 0;i < Sz;i++)
    {
        DFS(G[Vert][i],Level + 1);
        V[++Cnt] = Vert;
        L[Cnt] = Level;
    }
}

void Build_RMQ()
{
    for (int i = 2;i <= Cnt;i++)
        Lg[i] = Lg[i >> 1] + 1;

    for (int i = 0;i < ML;i++)
        P[i] = 1 << i;

    for (int i = 1;i <= Cnt;i++)
        RMQ[i][0] = i;

    for (int j = 1;P[j] <= Cnt;j++)
        for (int i = 1;i + P[j] <= Cnt;i++)
            if (L[RMQ[i][j - 1]] <= L[RMQ[i + P[j - 1]][j - 1]])
               RMQ[i][j] = RMQ[i][j - 1];
          else
               RMQ[i][j] = RMQ[i + P[j - 1]][j - 1];
}

int LCA(int X,int Y)
{
    int A = F[X],B = F[Y],C,D,Vert;

    if (A > B)
       swap(A,B);

    C = B - A + 1;
    D = Lg[C];
    Vert = RMQ[A][D];

    if (L[Vert] > L[RMQ[A + B - P[D]][D]])
       Vert = RMQ[B - P[D]][D];

    return V[Vert];
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);

     scanf("%d %d",&N,&M);

     for (int i = 2;i <= N;i++)
     {
         int X;
         scanf("%d",&X);
         G[X].push_back(i);
     }

     DFS(1,0);
     Build_RMQ();

     while (M--)
     {
         int X,Y;
         scanf("%d %d",&X,&Y);
         printf("%d\n",LCA(X,Y));
     }

  return 0;
}