Cod sursa(job #3352095)

Utilizator Minea_TheodorMinea Theodor Stefan Minea_Theodor Data 23 aprilie 2026 18:27:45
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m;
vector<int> graf[100005];
int niv[1000005];
int first[100005];
int rmq[20][200005];
int lg2[200005];
vector<int> euler;
void dfs(int a, int t)
{
    euler.push_back(a);
    first[a]=euler.size()-1;
    for(int i=0; i < graf[a].size(); i++)
    {
        if(t!=graf[a][i])
        {
            niv[graf[a][i]]=niv[a]+1;
            dfs(graf[a][i], a);
            euler.push_back(a);
        }
    }
}
void init()
{
    lg2[2]=1;
    for(int i=3; i <= euler.size()-1; i++)
        lg2[i]=lg2[i/2]+1;
}
void gen()
{
    init();
    for(int i=1; i < euler.size(); i++)
        rmq[0][i]=i;
    for(int i=1; (1<<i)<euler.size(); i++)
    {
        for(int j=1; j+(1<<i)<=euler.size(); j++)
        {
            if(niv[euler[rmq[i-1][j]]]<niv[euler[rmq[i-1][j+(1<<(i-1))]]])
                rmq[i][j]=rmq[i-1][j];
            else
                rmq[i][j]=rmq[i-1][j+(1<<(i-1))];
        }
    }
}
int query(int a, int b)
{
    int x = first[a];
    int y = first[b];
    if(x>y)
        swap(x, y);
    int lg = lg2[y-x+1];
    int c = y-(1<<lg)+1;
    if(niv[rmq[lg][x]] > niv[rmq[lg][c]])
        return euler[rmq[lg][c]];
    return euler[rmq[lg][x]];
}
int main()
{
    fin >> n >> m;
    for(int i=2; i <= n; i++)
    {
        int x;
        fin >> x;
        graf[x].push_back(i);
    }
    euler.push_back(0);
    dfs(1, 0);
    gen();
    while(m--)
    {
        int a, b;
        fin >> a >> b;
        fout << query(a, b) << '\n';
    }
    return 0;
}