Cod sursa(job #2633753)

Utilizator ElektrykT E S L A P E F E L I E Elektryk Data 8 iulie 2020 14:27:16
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.05 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;
    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];
    if ( a > b )
        swap ( a, 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';
}