Cod sursa(job #3346091)

Utilizator CheeseEaterHackRoman Alex CheeseEaterHack Data 12 martie 2026 16:09:16
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

vector<int> graf[100001];
int depth[100001], n, q, x, y;
int euler[200002], primaAp[100001], nivel[100001];
int timer, lg[200002], st[20][200002];

void dfs(int nod, int parinte) //EULER TOUR
{
    timer++;
    euler[timer]=nod;
    nivel[timer]=depth[nod];
    if (primaAp[nod]==0)
    {
        primaAp[nod]=timer;
    }
    for (auto vecin: graf[nod])
    {
        if (vecin==parinte) continue;
        depth[vecin]=depth[nod]+1;
        dfs(vecin, nod);
        timer++;
        euler[timer]=nod;
        nivel[timer]=depth[nod];
    }
}

void build_sparse()//in sparse retinem pozitia nivelului mic
{
    for (int i=1; i<=timer; i++)
    {
        st[0][i]=i;
    }
    for (int k=1;(1<<k)<=timer; k++)
    {
        for (int i=1; i+(1<<k)-1<=timer; i++)
        {
            int stg=st[k-1][i];
            int drp=st[k-1][i+(1<<(k-1))];
            if(nivel[stg]<=nivel[drp])
            {
                st[k][i]=stg;
            }
            else
            {
                st[k][i]=drp;
            }
        }
    }
    return;
}

int lcaquery(int a, int b)
{
    int stanga=primaAp[a];
    int dreapta=primaAp[b];
    if (stanga>dreapta)
    {
        swap(stanga, dreapta);
    }
    int k=lg[dreapta-stanga+1];
    int p1=st[k][stanga];
    int p2=st[k][dreapta-(1<<k)+1];
    int poz;
    if (nivel[p1]<nivel[p2])
    {
        poz=p1;
    }
    else
    {
        poz=p2;
    }
    return euler[poz];
}

int main()
{
    fin>>n>>q;
    for (int i=2; i<=n; i++)
    {
        fin>>x;
        graf[x].push_back(i);
        graf[i].push_back(x);
    }
    depth[1]=1;
    dfs(1, 0);
    lg[1]=0;
    for (int i=2; i<=timer; i++) //calculez logaritmii pt poz
    {
        lg[i]=lg[i/2]+1;
    }
    build_sparse();
    for (int i=1; i<=q; i++)
    {
        fin>>x>>y;
        fout<<lcaquery(x, y)<<'\n';
    }

    return 0;
}