Cod sursa(job #2989153)

Utilizator stefandutastefandutahoria stefanduta Data 6 martie 2023 00:53:34
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
#include <fstream>
#include <vector>
#include <cmath>
#define NMAX 100005
#define MMAX 2000005
#define LOG_MAX 17

using namespace std;

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

int father[NMAX];
int table[NMAX][LOG_MAX + 1];
int lvl[NMAX];
vector <int> adj[NMAX];

void dfs(int node)
{
    for (int i = 0; i < adj[node].size(); ++i)
    {
        int vecin = adj[node][i];
        lvl[vecin] = lvl[node] + 1;
        dfs(vecin);
    }
}

int lca(int a, int b)
{
    if (lvl[a] > lvl[b])
        swap(a, b);

    if (lvl[a] < lvl[b])
    {
        int log = log2(lvl[b] - lvl[a]);
        while (log >= 0 && lvl[b] > lvl[a])
        {
            if (lvl[b] - (1 << log) >= lvl[a])
                b = table[b][log];
            --log;
        }
    }

    if (a != b)
    {
        for (int i = LOG_MAX - 1; i >= 0; --i)
        {
            if (table[a][i] != 0 && table[a][i] != table[b][i])
            {
                a = table[a][i];
                b = table[b][i];
            }
        }

        a = table[a][0];
        b = table[b][0];
    }

    return a;
}

int main()
{
    int n, m, i, j, a, b, p;
    in >> n >> m;
    for (i = 2; i <= n; ++i)
    {
        in >> father[i];
        adj[father[i]].push_back(i);
        table[i][0] = father[i];
    }

    lvl[1] = 0;
    dfs(1);

    for (p = 1; p < LOG_MAX; ++p)
    {
        for (i = 1; i <= n; ++i)
            table[i][p] = table[table[i][p - 1]][p - 1];
    }

    for (i = 1; i <= m; ++i)
    {
        in >> a >> b;
        out << lca(a, b) << '\n';
    }
    return 0;
}