Cod sursa(job #1805804)

Utilizator teo.cons98Constantin Teodor-Claudiu teo.cons98 Data 14 noiembrie 2016 14:20:23
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.66 kb
#include<iostream>
#include<fstream>
#include<cmath>

using namespace std;

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

unsigned n, m;

unsigned tata[100001], tatasqrt[100001], radn, a, b, inaltime[100001];

void citire()
{
    int k, x, n1;
    bool e;
    fin>>n>>m;
    n1 = n;
    while(n1)
    {
        n1 /= 2;
        a++;
    }
    radn = sqrt(a);
    for(int i = 2; i <= n; ++i)
    {
        fin>>tata[i];
    }
    for(int i = 1; i <= a; ++i)
    {
        e = 0;
        for(int j = 2; j <= n; ++j)
        {
            if(inaltime[j] != inaltime[tata[j]] + 1)
            {
                inaltime[j] = inaltime[tata[j]] + 1;
                e = 1;
            }
        }
        if(e == 0) break;
    }
    for(int i = 2; i <= n; ++i)
    {
        k = tata[i];
        x = 1;
        while(tata[k] != 0 and x < radn + 1)
        {
            k = tata[k];
            ++x;
        }
        tatasqrt[i] = k;
    }

}

void parcurgere(unsigned a, unsigned b)
{
    int inala = inaltime[a], inalb = inaltime[b];
    if(inalb < inala)
    {
        swap(inalb, inala);
        swap(a, b);
    }
    while((inalb - inala) >= radn)
    {
        b = tatasqrt[b];
        inalb -= radn;
    }
    while(inalb - inala)
    {
        b = tata[b];
        --inalb;
    }
    while(tatasqrt[a] != tatasqrt[b])
    {
        a = tatasqrt[a];
        b = tatasqrt[b];
    }
    while(a != b)
    {
        a = tata[a];
        b = tata[b];
    }
    fout<<a<<'\n';
}

int main()
{
    citire();
    for(int i = 1; i <= m; ++i)
    {
        fin>>a>>b;
        parcurgere(a, b);
    }
}