Cod sursa(job #3328417)

Utilizator Victor5539Tanase Victor Victor5539 Data 8 decembrie 2025 15:57:41
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.69 kb
#include <bits/stdc++.h>

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

const int NMAX=1e5,PMAX=18;
int n,i,q,x,y,nr,start[NMAX+5],E[2*NMAX+5],depth[NMAX+5];
bool viz[NMAX+5];
vector <int> adj[NMAX+5];

struct RMQ{
int node,depth;}r[PMAX+5][2*NMAX+5];

void dfs(int node)
{
    viz[node]=1;
    nr++;
    r[0][nr].node=node;
    r[0][nr].depth=depth[node];
    start[node]=nr;

    for (auto node2: adj[node])
        if (!viz[node2])
            {
                depth[node2]=depth[node]+1;
                dfs(node2);

                nr++;
                r[0][nr].node=node;
                r[0][nr].depth=depth[node];
            }
}

void precalc()
{
    for (i=2; i<=nr; i++)
        E[i]=E[i>>1]+1;

    int p;
    for (p=1; (1<<p)<=nr; p++)
    {
        for (i=1; i<=nr; i++)
        {
            r[p][i]=r[p-1][i];

            if (i+(1<<(p-1))<=nr)
            {
                if (r[p-1][i+(1<<(p-1))].depth<r[p][i].depth)
                    r[p][i]=r[p-1][i+(1<<(p-1))];
            }
        }
    }
}

int lca(int x, int y)
{
    int st=start[x],dr=start[y];

    if (st>dr)
        swap(st,dr);

    int len=dr-st+1,e=E[len];

    RMQ Eda=r[e][st],Edase=r[e][dr-(1<<e)+1];

    if (Eda.depth<Edase.depth)
        return Eda.node;
    else
        return Edase.node;
}

int main()
{
    ios_base::sync_with_stdio(false);
    fin.tie(nullptr);

    fin>>n>>q;
    for (i=2; i<=n; i++)
    {
        fin>>x;
        adj[x].push_back(i);
        adj[i].push_back(x);
    }

    dfs(1);
    precalc();

    while (q--)
    {
        fin>>x>>y;
        fout<<lca(x,y)<<'\n';
    }
    return 0;
}