Cod sursa(job #2560298)

Utilizator Robys01Robert Sorete Robys01 Data 27 februarie 2020 21:21:56
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.69 kb
#include <bits/stdc++.h>
#define NMAX 100001
using namespace std;

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

int n, nr, k, vf[NMAX * 2], urm[NMAX * 2], last[NMAX];
int nre, eul[NMAX * 2], nivel[NMAX * 2], poz[NMAX];
int rmq[18][NMAX * 2];

void adauga(int nod, int tata)
{
    vf[++nr] = nod;
    urm[nr] = last[tata];
    last[tata] = nr;

}

void edfs(int nod, int tata, int niv)
{
    eul[++nre] = nod;
    nivel[nre] = niv;
    poz[nod] = nre;

    for(int k = last[nod]; k; k = urm[k])
        if( vf[k] != tata )
        {
            edfs(vf[k], nod, niv+1);
            eul[++nre] = nod;
            nivel[nre] = niv;

        }

}

void RMQ()
{
    for(int i=1; i<=nre; i++)
        rmq[0][i] = i;

    int rMax = log2(nre);

    for(int r = 1, l = 1; r<=rMax; r++, l*=2)
        for(int i = 1; i <= nre - l*2 + 1; i++)
        {
            if( nivel[ rmq[r-1][i] ] > nivel[ rmq[r-1][i+l] ] )
                rmq[r][i] = rmq[r-1][i+l];
            else
                rmq[r][i] = rmq[r-1][i];

        }

}


int lca(int a, int b)
{
    a = poz[a];
    b = poz[b];
    if(a > b)
        swap(a, b);

    int r = log2(b - a + 1);
    int l = (1<<r);
    int pozMin = 0;

    if( nivel[ rmq[r][a] ] > nivel[ rmq[r][b - l + 1] ] )
        pozMin =  rmq[r][b - l + 1] ;
    else
        pozMin =  rmq[r][a] ;

    return eul[pozMin];
}


int main()
{
    fin>>n>>k;
    for(int i=2; i<=n; i++)
    {
        int x; fin>>x;
        adauga(i, x);
        adauga(x, i);
    }

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

    return 0;
}