Cod sursa(job #2530345)

Utilizator andreiomd1Onut Andrei andreiomd1 Data 24 ianuarie 2020 18:09:37
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.04 kb
#include <bits/stdc++.h>

using namespace std;

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

typedef pair < int, int > PII;

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

int N, Q, A[NMAX], T[NMAX];

int M;
PII V[2 * NMAX];

int First[NMAX];

vector < int > G[NMAX];

int Log2[2 * NMAX];

PII rmq[LOGMAX][2 * NMAX];

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

    f >> N >> Q;

    for(int i = 2; i <= N; ++i)
        f >> T[i], G[T[i]].push_back(i);

    return;
}

static inline void Go (int Node, int Level)
{
    V[++M] = {Node, Level};

    if(!First[Node])
        First[Node] = M;

    for(auto it : G[Node])
    {
        Go(it, Level + 1);

        V[++M] = {Node, Level};
    }

    return;
}

static inline void Log2_Load ()
{
    Log2[1] = 0;

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

    return;
}

static inline void RMQ_Load ()
{
    for(int i = 1; i <= M; ++i)
        rmq[0][i] = V[i];

    for(int i = 1; i <= Log2[M]; ++i)
    {
        int Lg = (1 << i);

        for(int j = 1; j <= M - Lg + 1; ++j)
            if(rmq[i - 1][j].second < rmq[i - 1][j + (Lg >> 1)].second)
                rmq[i][j] = rmq[i - 1][j];
            else
                rmq[i][j] = rmq[i - 1][j + (Lg >> 1)];
    }

    return;
}

static inline int Find_Min (int p1, int p2)
{
    if(p1 > p2)
        swap(p1, p2);

    int Lg = p2 - p1 + 1;

    Lg = Log2[Lg];

    if(rmq[Lg][p1].second < rmq[Lg][p2 - (1 << Lg) + 1].second)
        return rmq[Lg][p1].first;

    return rmq[Lg][p2 - (1 << Lg) + 1].first;
}

static inline void Euler_Tour ()
{
    Go(Root, 1);

    Log2_Load();

    RMQ_Load();

    return;
}

static inline void Test_Case ()
{
    int u = 0, v = 0;

    f >> u >> v;

    g << Find_Min(First[u], First[v]) << '\n';

    return;
}

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

    return;
}

int main()
{
    Read();

    Euler_Tour();

    Solve();

    return 0;
}