Cod sursa(job #1473736)

Utilizator alex_ovidiunituAlex Ovidiu Nitu alex_ovidiunitu Data 20 august 2015 01:14:32
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.88 kb
#include <iostream>
#include <vector>
#include <fstream>
#define NMax 100015
using namespace std;
int n,m, nivel[NMax*32], E[NMax*32],k,prima_aparitie[NMax];
int a[20][NMax*32];// pentru rmq
vector <int> v[NMax];
// bag nod crt fii sai (samd) si apoi radacina
fstream f,g;
void parcurgere_Euler( int nod, int nivel_crt)
{
    E[++k] = nod;
    nivel[k] = nivel_crt;
    prima_aparitie[nod] = k; // unde se gaseste prima aparite a nodului pozitia k

    int i;

    for (i = 0 ; i < v[nod].size(); i++)
    {
        parcurgere_Euler(v[nod][i], nivel_crt+1);
        E[++k] = nod;
        nivel[k] = nivel_crt;
    }

}
void read()
{
    int i, tata;
    f>>n>>m;
    for (i = 2 ; i <= n ; i++)
    {
        f>>tata;
        v[tata].push_back(i);
    }
}

void range_minimum_query()
{
    //a[i][j] = min (E[j],....E[j+2^i-1]
    // a[i][j] = min(a[i-1][j],a[i-1][j + (1<<(i-1)) ]
    // o sa tin minte indicele unde se afla acel minim
    int i,j;
    for ( i = 1 ; i <= k ; i++ )
        a[0][i] = i;

    for (i = 1; (1<<i)<=k ; i++)
        for ( j = 1 ; j+(1<<i)<=k ; j++)
        {
            if (nivel[a[i-1][j]] <  nivel[a[i-1][j + (1<<(i-1)) ]])
                a[i][j] = a[i-1][j];
            else
                a[i][j] = a[i-1][j + (1<<(i-1)) ];
        }

}
int solve( int nod1, int nod2)
{
    int x = prima_aparitie[nod1];
    int y = prima_aparitie[nod2];
    if (y < x )
        swap(x,y);
    int dist = y-x  ;
    int putere = 0;
    while ( ( 1<<(putere + 1) ) <= dist )
        putere++;
    if ( nivel[ a[putere][x] ] < nivel[ a[putere][y-(1<<putere)+1] ])
        return E[a[putere][x]];
    else
        return E[a[putere][y-(1<<putere)+1]];
}
int main()
{
    int x,y;
    f.open("lca.in",ios::in);
    g.open("lca.out",ios::out);
    read();
    parcurgere_Euler(1,0);
    range_minimum_query();
    for (int i = 1; i <= m ; i++)
    {
        f>>x>>y;
        g<<solve(x, y)<<"\n";
    }
}