Cod sursa(job #2382836)

Utilizator ezioconnorVlad - Gabriel Iftimescu ezioconnor Data 18 martie 2019 18:25:20
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.62 kb
#include <bits/stdc++.h>

using namespace std;

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

int n, m, k;
int h[2 * 100001], L[2 * 100001], first[100001], lg[2 * 100001];
int rmq[20][4 * 100001];
vector <int> Muchii[100001];

inline void citire()
{
    int x;
    in >> n >> m;
    for (int i = 2; i <= n; ++i)
    {
        in >> x;
        Muchii[x].push_back(i);
    }
}

inline void DFS(int nod, int nivel)
{
    h[++k] = nod;
    L[k] = nivel;
    first[nod] = k;
    for (int i = 0; i < Muchii[nod].size(); ++i)
    {
        int vecin = Muchii[nod][i];
        DFS(vecin, nivel + 1);
        h[++k] = nod;
        L[k] = nivel;
    }
}

inline void RMQ()
{
    for (int i = 2; i <= k; ++i)
        lg[i] = lg[i >> 1] + 1;
    for (int i = 1; i <= k; ++i)
        rmq[0][i] = i;
    for (int i = 1; (1 << i) < k; ++i)
    {
        for (int j = 1; j <= k - (1 << i); ++j)
        {
            int l = 1 << (i - 1);
            rmq[i][j] = rmq[i - 1][j];
            if (L[rmq[i - 1][j + l]] < L[rmq[i][j]])
                rmq[i][j] = rmq[i - 1][j + l];
        }
    }
}

inline int LCA(int x, int y)
{
    int diff, l, sol, sh;
    int a = first[x], b = first[y];
    if (a > b)
        swap(a, b);
    diff = b - a + 1;
    l = lg[diff];
    sh = diff - (1 << l);
    sol = rmq[l][a];
    if (L[sol] > L[rmq[l][a + sh]])
        sol = rmq[l][a + sh];
    return h[sol];
}

int main()
{
    int x, y;
    citire();
    DFS(1, 0);
    RMQ();
    for (int i = 1; i <= m; ++i)
    {
        in >> x >> y;
        out << LCA(x, y) << '\n';
    }
    return 0;
}