Cod sursa(job #3308780)

Utilizator brianabucur11Briana Bucur brianabucur11 Data 27 august 2025 22:10:57
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.73 kb
//euler+aint

#include <bits/stdc++.h>

using namespace std;

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

const int nmax = 2e5 + 5;

vector <int> g[nmax];
int n, m, k, euler[nmax], lvl[nmax], poz[nmax], aint[4 * nmax];

void build (int nod, int h)
{
    euler[++k] = nod;
    lvl[k] = h;
    poz[nod] = k;
    for (auto it : g[nod])
    {
        build (it, h + 1);
        euler[++k] = nod;
        lvl[k] = h;
    }
}

void init (int nod, int st, int dr)
{
    if (st == dr)
    {
        aint[nod] = st;
        return;
    }
    int mij = (st + dr) / 2;
    init (2 * nod, st, mij);
    init (2 * nod + 1, mij + 1, dr);
    aint[nod] = aint[2 * nod];
    if (lvl[aint[2 * nod]] > lvl[aint[2 * nod + 1]])
        aint[nod] = aint[2 * nod + 1];
}

int query (int nod, int st, int dr, int p, int q)
{
    if (p <= st && dr <= q)
        return aint[nod];
    int cl = 0, cr = 0;
    int mij = (st + dr) / 2;
    if (p <= mij)
        cl = query (2 * nod, st, mij, p, q);
    if (mij + 1 <= q)
        cr = query (2 * nod + 1, mij + 1, dr, p, q);
    int sol = -1;
    if (cl != 0)
        sol = cl;
    if (cr != 0)
    {
        if (sol == -1 || lvl[cr] < lvl[sol])
            sol = cr;
    }
    return sol;
}

int lca (int x, int y)
{
    x = poz[x];
    y = poz[y];
    if (x > y)
        swap (x, y);
    return euler[query (1, 1, k, x, y)];
}

int main ()
{
    fin >> n >> m;
    for (int i = 2; i <= n; i++)
    {
        int x;
        fin >> x;
        g[x].push_back (i);
    }
    build (1, 1);
    init (1, 1, k);
    for (int i = 1; i <= m; i++)
    {
        int x, y;
        fin >> x >> y;
        fout << lca (x, y) << '\n';
    }
    return 0;
}