Cod sursa(job #3340221)

Utilizator AndreiEsteNebunAndrei Mateescu AndreiEsteNebun Data 12 februarie 2026 20:15:17
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.54 kb
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>

using namespace std;

string filename = "lca";
ifstream fin(filename + ".in");
ofstream fout(filename + ".out");

const int NMAX = 1e5;
const int LMAX = 17;
vector<int> adj[NMAX + 5];
int depth[NMAX + 5];
int lg[NMAX + 5];
int lift[NMAX + 5][22];

void precalc()
{
    for(int i=2;i<=NMAX;i++)
    {
        lg[i] = lg[i/2] + 1;
    }
}

void dfs(int node, int parent)
{
    lift[node][0] = parent;
    depth[node] = depth[parent] + 1;

    for(int put=1;put<=LMAX;put++)
        lift[node][put] = lift[lift[node][put-1]][put-1];

    for(auto it : adj[node])
    {
        if(it==parent)
            continue;

        dfs(it,node);
    }
}

int lca(int u,int v)
{
    if(depth[u] < depth[v])
        swap(u,v);

    int diff = depth[u] - depth[v];
    for(int i=0;i<=LMAX;i++)
    {
        if((1<<i)&diff)
        {
            u = lift[u][i];
        }
    }

    if(u==v)
        return u;

    for(int i=LMAX;i>=0;i--)
    {
        if(lift[u][i]!=lift[v][i])
        {
            u = lift[u][i];
            v = lift[v][i];
        }
    }
    return lift[u][0];
}

int main()
{
    precalc();
    int n,m;
    fin>>n>>m;
    for(int i=2;i<=n;i++)
    {
        int p;
        fin>>p;
        adj[p].push_back(i);
        adj[i].push_back(p);
    }
    depth[1] = 0;
    dfs(1,0);

    while(m--)
    {
        int u,v;
        fin>>u>>v;
        fout<<lca(u,v)<<'\n';
    }
}