Cod sursa(job #3219530)

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

#define nmax 100003
#define log 320

int n, m, a, b, pas;
int tata[nmax], 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)
    {
        f >> tata[i];
        fiu[tata[i]].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 + 1; ++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 (last[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;
}