Cod sursa(job #2984725)

Utilizator Matei_MunteanuMunteanu Matei Ioan Matei_Munteanu Data 24 februarie 2023 18:48:39
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.58 kb
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 100004;
const int K = 17;

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

int n, q;
vector<int> adj[NMAX];

struct LowestCommonAncestor
{
    int t_in[NMAX];
    int t_out[NMAX];
    int dfstimer;
    int up[NMAX][K + 4];

    void dfs(int v, int p)
    {
        t_in[v] = ++dfstimer;
        up[v][0] = p;
        for (int i = 1; i <= K; i++)
        {
            up[v][i] = up[up[v][i - 1]][i - 1];
        }
        for (int u : adj[v])
        {
            if (u != p)
            {
                dfs(u, v);
            }
        }
        t_out[v] = ++dfstimer;
    }

    void init()
    {
        dfstimer = 0;
        dfs(1, 1);  
    }

    bool is_ancestor(int u, int v)
    {
        return (t_in[u] <= t_in[v] && t_out[u] >= t_out[v]);
    }

    int lca(int u, int v)
    {
        if (is_ancestor(u, v))
        {
            return u;
        }
        if (is_ancestor(v, u))
        {
            return v;
        }
        for (int i = K; i >= 0; i--)
        {
            if (!is_ancestor(up[u][i], v))
            {
                u = up[u][i];
            }
        }
        return up[u][0];
    }
} LCA;

int main()
{
    fin >> n >> q;
    for (int i = 2; i <= n; i++)
    {
        int a;
        fin >> a;
        adj[a].push_back(i);
        adj[i].push_back(a);
    }
    LCA.init();
    for (int i = 1; i <= q; i++)
    {
        int a, b;
        fin >> a >> b;
        fout << LCA.lca(a, b) << '\n';
    }
    return 0;
}