Cod sursa(job #1346996)

Utilizator hopingsteamMatraguna Mihai-Alexandru hopingsteam Data 18 februarie 2015 18:43:14
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
#include <fstream>
#include <vector>
#define NMax 100005
#define LMax 20
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

int N,M,F[LMax][NMax],Log[NMax],Level[NMax];
vector<int> G[NMax];

void Read()
{
    fin>>N>>M;
    for(int i=2;i<=N;i++)
    {
        fin>>F[0][i];
        G[F[0][i]].push_back(i);
    }

}

void DFS(int Node)
{
    for(int i = 0; i<(int)G[Node].size();i++)
    {
        int Vecin = G[Node][i];
        Level[Vecin] = Level[Node] + 1;
        DFS(Vecin);
    }
}

void Precalculate()
{
    DFS(1);

    for(int i=2;i<=N;i++)
        Log[i] = Log[i/2] + 1;

    for(int i=1;(1<<i)<=N;i++)
        for(int j=1;j<=N;j++)
            F[i][j] = F[i-1][F[i-1][j]];
}

int LCA(int x, int y)
{
    if(Level[x]>Level[y])
        swap(x,y);

   while(Level[x]!=Level[y])
   {
       int K = Log[Level[y]-Level[x]];
       y = F[K][y];
   }

    for(int K = Log[Level[x]]; K>=0 ;K--)
    {
        if(F[K][x]!=F[K][y])
        {
            y = F[K][y];
            x = F[K][x];
        }
    }

    return F[0][x];
}

void SolveandPrint()
{
    while(M--)
    {
       int x,y;
       fin>>x>>y;
       fout<<LCA(x,y)<<"\n";
    }
}

int main()
{
    Read();
    Precalculate();
    SolveandPrint();
    return 0;
}