Cod sursa(job #2594012)

Utilizator CriogeniXBociat Daniel Tiberiu CriogeniX Data 5 aprilie 2020 11:01:59
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.4 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMax = 100000;
vector <int> G[NMax + 5];
int A[20][NMax + 5], Level[NMax + 5],Log2[NMax + 5];
int N,M;
void Read()
{
    fin >> N >> M;
    for(int i = 2; i <= N; ++i)
    {
        fin >> A[0][i];
        G[A[0][i]].push_back(i);
    }
}

void Precalculate()
{
    for(int i = 2; i <= N; ++i)
        Log2[i] = Log2[i/2] + 1;
    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]];
}

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 = Log2[Level[x] - Level[y]];
        x = A[K][x];
    }
    if(x == y)
        return x;
    for(int i = Log2[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()
{
    while(M--)
    {
        int x,y;
        fin >> x >> y;
        fout << LCA(x,y) << "\n";
    }
}

int main()
{
    Read();
    Precalculate();
    DFS(1);
    SolveAndPrint();
    return 0;
}