Cod sursa(job #2633743)

Utilizator mariamirabella2Bucur-Sabau Maria-Mirabela mariamirabella2 Data 8 iulie 2020 14:02:36
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.02 kb
 #include <fstream>
#include <vector>

using namespace std;

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

void dfs ( int nod, int niv );

void famiUnEuler ();

void famiUnRMQ ();

void lca ( int a, int b );

int n, m;

int a, b;

int ind[100137];

int nivel[500137];

int lg2[500137];

int rmq[20][200137];

int euler[200137];

vector < int > v[100137];

int main()
{
    in >> n >> m;
    for ( register int i = 2 ; i <= n ; ++i )
    {
        in >> a;
        v[a].push_back (i);
    }
    famiUnEuler ();
    /*for ( register int i = 1 ; i <= euler[0] ; ++i )
        out << euler[i] << " ";
    out << '\n';
    for ( register int i = 1 ; i <= euler[0] ; ++i )
        out << nivel[i] << " ";
    out << '\n';*/
    famiUnRMQ ();
    for ( register int i = 1 ; i <= m ; ++i )
    {
        in >> a >> b;
        lca ( a, b );
    }
    return 0;
}

void famiUnEuler ()
{
    dfs ( 1, 1 );
}

void dfs ( int nod, int niv )
{
    euler[++euler[0]] = nod;;
    nivel[euler[0]] = niv;
    ind[nod] = euler[0];
    for ( auto i : v[nod] )
    {
        dfs ( i, niv + 1 );
        euler[++euler[0]] = nod;
        nivel[euler[0]] = niv;
    }
}

void famiUnRMQ ()
{
    int k = euler[0];
    for ( register int i = 2 ; i <= k ; ++i )
        lg2[i] = lg2[i / 2] + 1;
    for ( register int i = 1 ; i <= k ; ++i )
        rmq[0][i] = i; // pui indicele deoarce vei compara dupa nivele nu dupa  nod
    for ( register int i = 1 ; i <= lg2[k] ; ++i )
    {
        int put = ( 1 << i );
        for ( register int j = 1 ; j <= k - put / 2 ; ++j )
            if(nivel[rmq[i-1][j]] < nivel[rmq[i-1][j+put/2]])
			rmq[i][j] = rmq[i-1][j];
	else
				rmq[i][j] = rmq[i-1][j + put/2];

    }
}

void lca ( int a, int b )
{
    a = ind[a];
    b = ind[b];
    int lg = lg2[b - a + 1];
    if ( nivel[rmq[lg][a]] < nivel[rmq[lg][b - ( 1 << lg ) + 1]] )
        out << euler[rmq[lg][a]] << '\n';
    else
        out << euler[rmq[lg][b - ( 1 << lg ) + 1]] << '\n';
}