Cod sursa(job #3361322)

Utilizator EricDimiCismaru Eric-Dimitrie EricDimi Data 23 iulie 2026 10:49:05
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.72 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 depth[MAX_N + 1];
int n, q;

void swap(int& a, int& b)
{
    a ^= b; /// a <- a ^ b
    b ^= a; /// b <- b ^ (a ^ b) = a
    a ^= b; /// a <- (a ^ b) ^ a = b
}

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

void Preprocess()
{
    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)
{
    for(int child : adj[node])
    {
        depth[child] = 1 + depth[node];
        DFS(child);
    }
}

int KthAncestor(int node, int k)
{
    for(int bit = 0; bit <= MAX_LOG2; bit++)
        if(k & (1 << bit))
            node = ancestor[bit][node];
    return node;
}

int LCA(int x, int y)
{
    if(depth[x] < depth[y])
        swap(x, y);
    x = KthAncestor(x, depth[x] - depth[y]);
    if(x == y)
        return x;
    for(int bit = MAX_LOG2; bit >= 0; bit--)
        if(ancestor[bit][x] != ancestor[bit][y])
        {
            x = ancestor[bit][x];
            y = ancestor[bit][y];
        }
    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;
}