Cod sursa(job #3343906)

Utilizator andrei_nAndrei Nicolae andrei_n Data 28 februarie 2026 18:16:42
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.64 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");

int n, m;
vector <int> g[100001];
int tata[100001];

int h[100001];
int rmq[20][100001]; //al 2^i lea stramos al lui node

void calc_rmq()
{
    for (int node = 1; node <= n; node++)
        rmq[0][node] = tata[node];

    for (int i = 1; i <= 19; i++)
        for (int node = 1; node <= n; node++)
            rmq[i][node] = rmq[i - 1][rmq[i - 1][node]];
}

void dfs_h(int node, int parent)
{
    h[node] = h[parent] + 1;
    for (auto vecin : g[node])
        if (vecin != parent)
            dfs_h(vecin, node);
}

int lca(int x, int y)
{
    int stramosx, stramosy;
    if (x == y)
        return x;
    for (int i = 20; i >= 0; i--)
    {
        stramosx = rmq[i][x];
        stramosy = rmq[i][y];
        if (stramosx != stramosy)
        {
            x = stramosx;
            y = stramosy;
        }
    }
    return tata[x];
}

int main()
{
    fin >> n >> m;

    tata[1] = 0;
    for (int i = 1; i <= n - 1; i++)
    {
        int node;
        fin >> node;
        g[i + 1].push_back(node);
        g[node].push_back(i + 1);
        tata[i + 1] = node;
    }

    dfs_h(1, 0);
    calc_rmq();

    for (int i = 1; i <= m; i++)
    {
        int x, y;
        fin >> x >> y;

        if (h[x] < h[y])
            swap(x, y);

        int dh = h[x] - h[y];

        for (int i = 0; (1 << i) <= dh; i++)
            if (dh & (1 << i))
            {
                dh -= (1 << i);
                x = rmq[i][x];
            }

        fout << lca(x, y) << '\n';
    }
    return 0;
}