Cod sursa(job #2774406)

Utilizator vlad2009Vlad Tutunaru vlad2009 Data 11 septembrie 2021 15:43:28
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.78 kb
#include <fstream>
#include <vector>

using namespace std;

const int Nmax = 200000;
int h[Nmax + 1], l[Nmax + 1];
int rmq[Nmax + 1][18], log[Nmax + 1];
vector <int> adj[Nmax + 1];
vector <int> euler;
bool viz[Nmax + 1];
int n, k = 1;

void dfs(int node, int q = 0)
{
    viz[node] = true;
    euler.push_back(node);
    l[node] = euler.size();
    h[node] = q;
    for (auto u : adj[node])
    {
        if (!viz[u])
        {
            dfs(u, q + 1);
            euler.push_back(node);
        }
    }
}

void RMQ()
{
    for (int i = 2; i <= n; i++)
    {
        log[i] = log[i / 2] + 1;
    }
    for (int i = 1; i <= n; i++)
    {
        rmq[i][0] = i;
    }
    for (int j = 1; j <= 17; j++)
    {
        for (int i = 1; i + (1 << j) <= n; i++)
        {
            int x = rmq[i][j - 1], y = rmq[i + (1 << (j - 1))][j - 1];
            if (h[euler[x - 1]] < h[euler[y - 1]])
            {
                rmq[i][j] = x;
            }
            else
            {
                rmq[i][j] = y;
            }
        }
    }
}

int lca(int u, int v)
{
    if (l[u] > l[v])
    {
        swap(u, v);
    }
    int j = log[l[v] - l[u] + 1];
    int x = rmq[l[u]][j], y = rmq[l[v] - (1 << j) + 1][j];
    if (h[euler[x - 1]] < h[euler[y - 1]])
    {
        return euler[x - 1];
    }
    else
    {
        return euler[y - 1];
    }
}

int main()
{
    ifstream fin("lca.in");
    ofstream fout("lca.out");
    int m;
    fin >> n >> m;
    for (int i = 2; i <= n; i++)
    {
        int nr;
        fin >> nr;
        adj[nr].push_back(i);
    }
    dfs(1);
    n = euler.size();
    RMQ();
    while (m--)
    {
        int u, v;
        fin >> u >> v;
        fout << lca(u, v) << "\n";
    }
    return 0;
}