Cod sursa(job #3219551)

Utilizator raresOObreja Rares raresO Data 31 martie 2024 17:05:53
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.26 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");

#define nmax 100003
#define log 18

int n, m, a, b, pas;
int fst[nmax], last[nmax], nivel[nmax];
int rmq[log][2 * nmax], put[2 * nmax];
vector<int> fiu[nmax];

void dfs(int nod, int niv)
{
    rmq[0][++pas] = nod;

    if (!fst[nod])
    {
        nivel[nod] = niv;
        fst[nod] = pas;
    }

    int nr = fiu[nod].size();
    for (int i = 0; i < nr; ++i)
    {
        int next = fiu[nod][i];
        dfs(next, niv + 1);
        rmq[0][++pas] = nod;
    }
    last[nod] = pas;
}

int main()
{
    f >> n >> m;
    for (int i = 2; i <= n; ++i)
    {
        int x;
        f >> x;
        fiu[x].push_back(i);
    }
    dfs(1, 1);
    // for (int i = 1; i <= pas; ++i)
    // {
    //     g << fst[i] << ' ' << last[i] << '\n';
    //     g << rmq[0][i] << ' ';
    // }

    for (int i = 2; i <= n; ++i)
    {
        put[i] = put[i / 2] + 1;
    }

    for (int i = 1; i < log; ++i)
    {
        int p = 1 << (i - 1);
        for (int j = 1; j <= pas - p; ++j)
        {
            rmq[i][j] = rmq[i - 1][j];
            if (nivel[rmq[i - 1][j]] > nivel[rmq[i - 1][j + p]])
            {
                rmq[i][j] = rmq[i - 1][j + p];
            }
        }
    }

    // for (int i = 0; i < 10; ++i)
    // {
    //     for (int j = 1; j <= pas; ++j)
    //     {
    //         g << rmq[i][j] << ' ';
    //     }
    //     g << '\n';
    // }

    for (int i = 1; i <= m; ++i)
    {
        f >> a >> b;

        if (fst[a] < fst[b] && last[a] > last[b])
        {
            g << a << '\n';
            continue;
        }
        if (fst[b] < fst[a] && last[b] > last[a])
        {
            g << b << '\n';
            continue;
        }

        if (fst[a] > fst[b])
        {
            swap(a, b);
        }
        int pa = last[a];
        int pb = fst[b];
        int lg = pb - pa + 1;
        lg = put[lg];
        // g << lg << "\n";
        int val = rmq[lg][pa];
        if (nivel[rmq[lg][pa]] > nivel[rmq[lg][pb - (1 << lg) + 1]])
        {
            val = rmq[lg][pb - (1 << lg) + 1];
        }
        g << val << '\n';
    }
    return 0;
}