Cod sursa(job #3369287)

Utilizator Mihai09Mihai Arteni Mihai09 Data 19 octombrie 2026 12:27:40
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.77 kb
#include <bits/stdc++.h>

using namespace std;

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

int n,m,niv[100010],up[100010],k,start[100010],maxlog[100010];
list<int>ofs[100010];
pair<int,int>v[200010],rmq[100010][20];

void dfs(int x)
{
    k++;
    if(start[x] == 0)
    {
        start[x] = k;
    }
    v[k] = {x,niv[x]};
    for(int s:ofs[x])
    {
        niv[s] = niv[x]+1;
        dfs(s);
        k++;
        v[k] = {x,niv[x]};
    }
}

int eval(int a,int b)
{
    int len = b-a+1;
    int lenlog = maxlog[len];
    if(rmq[a][lenlog].second < rmq[b- (1<<lenlog) + 1][lenlog].second)
    {
        return max(1,rmq[a][lenlog].first);
    }
    else
    {
        return max(1,rmq[b- (1<<lenlog) + 1][lenlog].first);
    }
}


int main()
{
    fin >>n >>m;
    for(int i = 1;i <= n-1;i++)
    {
        fin >>up[i+1];
        ofs[up[i+1]].push_back(i+1);
    }
    niv[1] = 1;
    dfs(1);
    for(int i = 1;i <= n;i++)
    {
        maxlog[i] = maxlog[i/2]+1;
    }
    for(int i = 1;i <= k;i++)
    {
        rmq[i][0] = v[i];
    }
    for(int i = 1;i <= maxlog[n];i++)
    {
        for(int j = 1;j <= k;j++)
        {
            if(j + (1<<i) - 1 <= k)
            {
                int idk = j+(1<<(i-1));
                if(rmq[j][i-1].second < rmq[idk][i-1].second)
                {
                    rmq[j][i] = rmq[j][i-1];
                }
                else
                {
                    rmq[j][i] = rmq[idk][i-1];
                }
            }
        }
    }
    while(m--)
    {
        int u,v;
        fin >>u >>v;
        u = start[u];
        v = start[v];
        if(u > v)
        {
            swap(u,v);
        }
        fout <<eval(u,v)<<"\n";
    }
    return 0;
}