Cod sursa(job #2808460)

Utilizator andreiomd1Onut Andrei andreiomd1 Data 25 noiembrie 2021 09:42:59
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.71 kb
#include <fstream>
#include <vector>

using namespace std;

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

const int NMAX = 1e5 + 1, LOGMAX = 17;
const int ROOT =  1;

int Log2[NMAX];

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

vector < int > G[NMAX];

int Level[NMAX];

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

    f >> N >> Q;
    Log2[1] = 0;

    for(int i = 2; i <= N; ++i)
        f >> t[0][i], G[t[0][i]].push_back(i), Log2[i] = 1 + Log2[(i >> 1)];

    return;
}

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

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

    return;
}

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

    DFS(ROOT);

    return;
}

static inline void my_swap (int &x, int &y)
{
    x = (x ^ y), y = (x ^ y), x = (x ^ y);

    return;
}

static inline void TestCase ()
{
    int X = 0, Y = 0;
    f >> X >> Y;

    if(X == Y)
    {
        g << X << '\n';

        return;
    }

    if(Level[X] > Level[Y])
        my_swap(X, Y);

    int Diff = Level[Y] - Level[X];
    for(int i = Log2[Diff]; i >= 0; --i)
        if(Diff & (1 << i))
            Y = t[i][Y];

    if(X == Y)
    {
        g << X << '\n';

        return;
    }

    int keep = Level[X];
    for(int i = Log2[keep]; i >= 0; --i)
        if(t[i][X] != t[i][Y])
            X = t[i][X], Y = t[i][Y];

    g << t[0][X] << '\n';

    return;
}

static inline void Solve ()
{
    while(Q--)
        TestCase();

    return;
}

int main()
{
    Read();

    Precalculation();

    Solve();

    return 0;
}