Cod sursa(job #3302317)

Utilizator Carnu_EmilianCarnu Emilian Carnu_Emilian Data 6 iulie 2025 11:39:00
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
typedef long long ll;
typedef long double ld;

const int N = 1e5 + 5;
int n, m, v[N], p[17][N], a, b;
pair<int, int> f[N];
vector<int> g[N];

void parcEuler(int nod)
{
    a++;
    if (f[nod].first == 0)
        f[nod].first = a;
    for (int e : g[nod])
        parcEuler(e);
    a++;
    f[nod].second = a;
}

bool ancestor(int a, int b)
{
    /// este a un ancestor de-al lui b?
    return f[a].first <= f[b].first && f[b].second <= f[a].second;
}

int main()
{
    fin >> n >> m;
    for (int i = 2; i <= n; i++)
    {
        fin >> v[i];
        g[v[i]].push_back(i);
    }
    parcEuler(1);
    for (int i = 2; i <= n; i++)
        p[0][i] = v[i];
    for (int a = 1; (1 << a) <= n; a++)
        for (int i = 2; i <= n; i++)
            p[a][i] = p[a - 1][p[a - 1][i]];

    while (m--)
    {
        fin >> a >> b;
        if (ancestor(a, b))
        {
            fout << a << '\n';
            continue;
        }
        else if (ancestor(b, a))
        {
            fout << b << '\n';
            continue;
        }

        for (int i = 16; i >= 0; i--)
        {
            if (p[i][a] == 0)
                continue;
            if (i == 0 && ancestor(p[i][a], b))
                a = p[i][a];
            else if (!ancestor(p[i][a], b))
                a = p[i + 1][a];
        }
        fout << a << '\n';
    }
    fin.close();
    fout.close();
    return 0;
}