Cod sursa(job #2626649)

Utilizator andreiomd1Onut Andrei andreiomd1 Data 7 iunie 2020 12:54:14
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.49 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

const int NMAX = 1e5 + 5, LOGMAX = 20, ROOT = 1;

int N, Q;
int Next[LOGMAX][NMAX];

int Level[NMAX];

vector < int > G[NMAX];

static inline void Read ()
{
    f.tie(nullptr);

    f >> N >> Q;

    for(int i = 1; i < N; ++i)
    {
        int X = 0;
        f >> X;

        Next[0][(i + 1)] = X;
        G[X].push_back((i + 1));
    }

    return;
}

static inline void DFS (int Node, int Lvl)
{
    Level[Node] = Lvl;

    for(auto it : G[Node])
        DFS(it, Lvl + 1);

    return;
}

static inline void Precalculation ()
{
    for(int i = 1; (1 << i) <= N; ++i)
        for(int j = 1; j <= N; ++j)
            Next[i][j] = Next[i - 1][Next[i - 1][j]];

    DFS(ROOT, 0);

    return;
}

static inline int LCA (int X, int Y)
{
    if(X == Y)
        return X;

    if(Level[Y] < Level[X])
        swap(X, Y);

    int Diff = Level[Y] - Level[X];

    for(int i = 0; (1 << i) <= Diff; ++i)
        if(Diff & (1 << i))
            Y = Next[i][Y];

    if(X == Y)
        return X;

    for(int step = 15; step >= 0; --step)
        if(Next[step][X] && Next[step][X] != Next[step][Y])
            X = Next[step][X], Y = Next[step][Y];

    return Next[0][X];
}

int main()
{
    Read();

    Precalculation();

    while(Q--)
    {
        int a = 0, b = 0;
        f >> a >> b;

        g << LCA(a, b) <<'\n';
    }

    return 0;
}