Cod sursa(job #2906940)

Utilizator AndreiBOTOBotocan Andrei AndreiBOTO Data 27 mai 2022 22:49:39
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.43 kb
#include <fstream>

using namespace std;

const int NMAX=1e5+5;
const int LMAX=17;

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

int lvl[NMAX],log[NMAX];
int t[LMAX][NMAX];
int n;

int lca(int x, int y)
{
    int e=log[lvl[x]];
    while(e>=0)
    {
        if(t[e][x]!=t[e][y])
        {
            x=t[e][x];
            y=t[e][y];
        }
        e--;
    }
    return t[0][x];
}

void next(int x)
{
    if(lvl[x] != 0)
        return ;
    else
    {
    next(t[0][x]);
    lvl[x]=lvl[t[0][x]]+1;
    }
}

void next_lvl()
{
    int i;
    lvl[1]=1;
    for(i=2;i<=n;i++)
        next(i);
}

void next_t()
{
    int i,e;
    for(e=1;e<LMAX;e++)
        for(i=1;i<=n;i++)
            t[e][i]=t[e-1][t[e-1][i]];
}

int nextasc(int x, int ord)
{
    int e=0;
    while(ord!=0)
    {
        if(ord%2!=0)
            x=t[e][x];
        e++;
        ord=ord/2;
    }
    return x;
}

void next_log()
{
    int i;
    log[1]=0;
    for(i=2;i<=n;i++)
        log[i]=log[i/2]+1;
}

int main()
{
    int i,j,x,y,m;
    fin>>n>>m;
    for(i=2;i<=n;i++)
        fin>>t[0][i];
    next_t();
    next_lvl();
    next_log();
    for(i=0;i<m;i++)
    {
        fin>>x>>y;
        if(lvl[x]>lvl[y])
            swap(x,y);
        y=nextasc(y,lvl[y]-lvl[x]);
        if(y==x)
            fout<<x<<"\n";
        else
            fout<<lca(x,y)<<"\n";
    }
    return 0;
}