Cod sursa(job #2968966)

Utilizator Stefan_GhinescuGhinescu Stefan-George Stefan_Ghinescu Data 22 ianuarie 2023 13:49:08
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.8 kb
#include <cmath>
#include <vector>

#define notlocal 1

#if !notlocal

#include <iostream>
#define fin std::cin
#define fout std::cout

#else

#include <fstream>
std::ifstream fin("lca.in");
std::ofstream fout("lca.out");

#endif

using namespace std;

const int NMAX = 100000;

int v[NMAX + 5];
int rmq[NMAX + 5][20];

vector <int> G[NMAX + 5];
int euler[2 * NMAX + 5];
int level[NMAX + 5];
int eulerSize;
int firstEuler[NMAX + 5];

void dfs(int rad, int niv)
{
    firstEuler[rad] = eulerSize;
    euler[eulerSize++] = rad;
    level[rad] = niv;
    for (const int& it : G[rad])
    {
        dfs(it, niv + 1);
        euler[eulerSize++] = rad;
    }
}

int main()
{
    int n, m, a;
    fin >> n >> m;
    for (int i = 1; i < n; ++i)
    {
        fin >> a;
        G[a].push_back(i + 1);
    }
    dfs(1, 0);
    for (int i = 0; i < eulerSize; ++i)
    {
        rmq[i][0] = euler[i];
    }
    for (int i = eulerSize - 1; i > -1; --i)
    {
        for (int l = 1; i + (1 << l) < eulerSize + 1; ++l)
        {
            if (level[rmq[i][l - 1]] < level[rmq[i + (1 << (l - 1))][l - 1]])
            {
                rmq[i][l] = rmq[i][l - 1];
            }
            else
            {
                rmq[i][l] = rmq[i + (1 << (l - 1))][l - 1];
            }
        }
    }
    int x, y, l;
    for (int i = 0; i < m; ++i)
    {
        fin >> x >> y;
        x = firstEuler[x];
        y = firstEuler[y];
        if (y < x)
        {
            swap(x, y);
        }
        l = log2(y - x + 1);
        if (level[rmq[x][l]] < level[rmq[1 + y - (1 << l)][l]])
        {
            fout << rmq[x][l];
        }
        else
        {
            fout << rmq[1 + y - (1 << l)][l];
        }
        fout << '\n';
    }
    return 0;
}