Cod sursa(job #2869899)

Utilizator ana_madalina_18Radu Ana Madalina ana_madalina_18 Data 11 martie 2022 22:00:12
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.87 kb
#include <fstream>
#include <vector>
#include <cmath>
#include <iostream>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m;
int stramos[30][100009];
int nivel[100009] , vizitat[1000009];
vector <int> v[100009];
int logaritm;
void calc_stramosi()
{
    for(int exp=1;exp<=logaritm;exp++)
    {
        for(int nod=1;nod<=n;nod++)
        {
            stramos[exp][nod]=stramos[exp-1][stramos[exp-1][nod]];
            //cout<<stramos[exp][nod]<<' ';
        }
        //cout<<endl;
    }
}
void egalizare(int &a, int &b)
{
    int dif=nivel[b]-nivel[a];
    for(int i=logaritm;i>=0;i--)
    {
        int pow=(1<<i);
        if(pow<=dif)
        {
            dif-=pow;
            b=stramos[i][b];
        }

    }
}
int lca(int a, int b)
{
    if(nivel[a]>nivel[b])
    {
        int aux=a;
        a=b;
        b=aux;
    }
    if(nivel[a]!=nivel[b])
        egalizare(a,b);
    int stram_a=a, stram_b=b;
    if(stram_a==stram_b)
    {
        return stram_a;
    }
    for(int i=16;i>=0;i--)
    {
        if(stramos[i][stram_a]!=stramos[i][stram_b])
        {
            stram_a=stramos[i][stram_a];
            stram_b=stramos[i][stram_b];
        }
    }
    return stramos[0][stram_a];
}
void dfs(int x, int niv)
{
    vizitat[x]=1;
    nivel[x]=niv;
    for(int i=0;i<v[x].size();i++)
    {
        int vecin=v[x][i];
        if(vizitat[vecin]==0)
        {
            dfs(vecin,niv+1);
        }
    }
}
int main()
{
    fin>>n>>m;
    logaritm=log2(n);
    for(int i=2;i<=n;i++)
    {
        fin>>stramos[0][i];
        v[stramos[0][i]].push_back(i);
        //v[i].push_back(stramos[0][i]);
    }
    stramos[0][1]=1;
    calc_stramosi();
    dfs(1,1);

    for(int i=1;i<=m;i++)
    {
        int a, b;
        fin>>a>>b;
        fout<<lca(a,b)<<'\n';
    }
    return 0;
}