Cod sursa(job #3345110)

Utilizator Gabriel_DaescuDaescu Gabriel Florin Gabriel_Daescu Data 7 martie 2026 22:46:10
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.65 kb
#include <fstream>
#include <vector>
#define NMAX 100005
#define LOG 18
using namespace std;
ifstream  fin("lca.in");
ofstream fout("lca.out");
int N,M,poz,tata[NMAX],nivel[NMAX];
int first[NMAX],euler[2*NMAX],rmq[2*NMAX][LOG];
vector<int> tree[NMAX];

void citire()
{
    fin>>N>>M;

    for(int i=2; i<=N; i++)
    {
        fin>>tata[i];
        tree[tata[i]].push_back(i);
    }
}

void DFS(int nod)
{
    euler[++poz]=nod;
    first[nod]=poz;
    for(int i=0; i<tree[nod].size(); i++)
    {
        int next_nod=tree[nod][i];
        nivel[next_nod]=nivel[nod]+1;

        DFS(next_nod);
        euler[++poz]=nod;
    }
}

int lca(int a, int b)
{
    int st,dr;

    st=first[a];
    dr=first[b];

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

    int l=dr-st+1;
    int k=31-__builtin_clz(l);

    int x=rmq[st][k];
    int y=rmq[dr-(1<<k)+1][k];

    if(nivel[euler[x]]<nivel[euler[y]])
    {
        return euler[x];
    }
    else
    {
        return euler[y];
    }
}

int main()
{
    citire();

    poz=0;
    DFS(1);

    for(int i=1; i<=poz; i++)
    {
        rmq[i][0]=i;
    }

    for(int j=1; (1<<j)<=poz; j++)
    {
        for(int i=1; i+(1<<j)-1<=poz; i++)
        {
            int a=rmq[i][j-1];
            int b=rmq[i+(1<<(j-1))][j-1];

            if(nivel[euler[a]]<nivel[euler[b]])
            {
                rmq[i][j]=a;
            }
            else
            {
                rmq[i][j]=b;
            }
        }
    }

    int a,b;
    for(int q=1; q<=M; q++)
    {
        fin>>a>>b;

        fout<< lca(a,b) << "\n";
    }

    return 0;
}