Cod sursa(job #2950029)

Utilizator raileanu-alin-gabrielRaileanu Alin-Gabriel raileanu-alin-gabriel Data 2 decembrie 2022 17:26:16
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.64 kb
#include <fstream>
#include <vector>
const int EULMAX=4000005;
const int NMAX=1000005;

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

struct euler
{
    int nod, niv;
}eul[EULMAX];

void dfs(int, int);
void constr_rmq();
int lca(int, int);

vector <int> v[NMAX];
int rmq[32][NMAX], fap[NMAX];
int n, m, lge;


int main()
{
    int i, a, b;
    fin>>n>>m;
    for(i=2; i<=n; i++)
    {
        fin>>a;
        v[i].push_back(a);
        v[a].push_back(i);
    }
    dfs(1, 0);
    constr_rmq();
    for(i=1; i<=m; i++)
    {
        fin>>a>>b;
        fout<<lca(a, b)<<'\n';
    }
    return 0;
}

void dfs(int nod, int lvl)
{
    eul[++lge]={nod, lvl};
    fap[nod]=lge;
    for(auto i:v[nod])
    {
        if(fap[i]==0)
        {
            dfs(i, lvl+1);
            eul[++lge]={nod, lvl};
        }
    }
}

void constr_rmq()
{
    int i, j;
    for(i=1; i<=lge; i++) rmq[0][i]=i;
    for(i=1; (1<<i)<=lge; i++)
    {
        for(j=1; j<=lge-(1<<i)+1; j++)
        {
            if(eul[rmq[i-1][j]].niv<eul[rmq[i-1][j+(1<<(i-1))]].niv)
            {
                rmq[i][j]=rmq[i-1][j];
            }
            else
            {
                rmq[i][j]=rmq[i-1][j+(1<<(i-1))];
            }
        }
    }
}

int lca(int a, int b)
{
    int lg, pt=0;

    if(fap[a]>fap[b]) swap(a, b);
    lg=fap[b]-fap[a]+1;

    while((1<<(pt+1))<=lg) pt++;
    
    if(eul[rmq[pt][fap[b]-(1<<pt)+1]].niv>eul[rmq[pt][fap[a]]].niv) 
    {
        return eul[rmq[pt][fap[a]]].nod;
    }
    else 
    {
        return eul[rmq[pt][fap[b]-(1<<pt)+1]].nod;
    }
}