Cod sursa(job #3361283)

Utilizator EricDimiCismaru Eric-Dimitrie EricDimi Data 22 iulie 2026 19:33:29
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

const int MAX_N = 100000,
          MAX_LOG2 = 17;

vector<int> adj[MAX_N + 1];
int ancestor[MAX_LOG2 + 1][MAX_N + 1];
int tin[MAX_N + 1], tout[MAX_N + 1];
int parent[MAX_N + 1];
int n, q;

void Read()
{
    f >> n >> q;
    for(int v = 2; v <= n; v++)
    {
        int u;
        f >> u;
        parent[v] = u;
        adj[u].push_back(v);
    }
}

void Preprocess()
{
    for(int i = 1; i <= n; i++)
        ancestor[0][i] = parent[i];
    for(int k = 1; k <= MAX_LOG2; k++)
        for(int i = 1; i <= n; i++)
            if(ancestor[k - 1][i])
                ancestor[k][i] = ancestor[k - 1][ancestor[k - 1][i]];
}

int timer = 0;

void DFS(int node)
{
    tin[node] = (++timer);
    for(int child : adj[node])
        DFS(child);
    tout[node] = (++timer);
}

inline bool Ancestor(int x, int y)
{
    return tin[x] <= tin[y] && tout[y] <= tout[x];
}

int LCA(int x, int y)
{
    if(Ancestor(x, y))
        return x;
    if(Ancestor(y, x))
        return y;
    for(int k = MAX_LOG2; k >= 0; k--)
    {
        int z = ancestor[k][x];
        if(z && !Ancestor(z, y))
            x = z;
    }
    return ancestor[0][x];
}

void Solve()
{
    while(q--)
    {
        int x, y;
        f >> x >> y;
        g << LCA(x, y) << '\n';
    }
}

int main()
{
    Read();
    Preprocess();
    DFS(1);
    Solve();

    f.close();
    g.close();

    return 0;
}