Cod sursa(job #1771469)

Utilizator PaulStighiStiegelbauer Paul-Alexandru PaulStighi Data 5 octombrie 2016 17:52:16
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.42 kb
#include <fstream>
#include <vector>
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

const int NMax = 100005;
int N,Q,TT[NMax],Level[NMax];
int A[20][NMax];
int Log[NMax];
vector<int> G[NMax];

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

void Precalculate()
{
    for(int i = 1 ; 1<<i <= N ; ++i)
    {
        for(int j = 1 ; j <= N ; ++j)
            A[i][j] = A[i-1][A[i-1][j]];
    }

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

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

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

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

    if(x==y)    return x;

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

    return A[0][x];
}

void SolveandPrint()
{
    DFS(1);

    while(Q--)
    {
        int x,y;
        fin>>x>>y;

        fout<<LCA(x,y)<<"\n";
    }
}

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