Cod sursa(job #2051333)

Utilizator Victor24Vasiesiu Victor Victor24 Data 28 octombrie 2017 20:08:54
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.92 kb
#include <bits/stdc++.h>
#define x first
#define y second

using namespace std;

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

vector < int > v[100005];

int n, m, poz1, poz2, i, j, x, nodniv[100005], lg[100005], d = 2, rmq[30][100005], a, b, eul[500005], cnt, fv[100005], ap[100005], lv;

void euler ( int nod, int niv )
{
    if ( fv[nod] )
    {
        return;
    }

    fv[nod] = 1;

    nodniv[nod] = niv;

    cnt++;
    eul[cnt] = nod;
    ap [ nod ] = cnt;

    for ( int i = 0 ; i < v[nod].size() ; i++ )
    {
        if ( !fv [ v[nod][i] ] )
        {
            euler( v[nod][i] , niv+1 );
            cnt++;
            eul[cnt] = nod;
        }
    }

}

int main()
{
    fin>>n>>m;

    for ( i = 2; i <= n ; i++ )
    {
        fin>>x;
        v[x].push_back( i );
        v[i].push_back( x );

    }

    euler(1, 1);


    n = cnt;

    for ( i = 2 ; i <= n ; i++ )
    {
        lg[i] = lg[i/2] + 1;
    }

    for ( i = 1; i <= n ; i++ )
    {
        rmq[0][i] = eul[i];
    }
    for ( i = 1 ; i <= lg[n] ; i++ )
    {
        for ( j = 1; j <= n ; j++ )
        {
            if (  nodniv[ rmq[ i - 1 ][ j ] ] < nodniv [ rmq[ i - 1 ][ j + ( 1 << (i - 1) )  ] ] )
            {
                rmq [ i ][ j ] = rmq [ i - 1 ][ j ];
            }
            else
            {
                rmq[ i ][ j ] = rmq[ i - 1 ][ j + ( 1 << (i - 1 ) ) ];
            }
        }
    }

    for ( i = 1; i <= m ; i++ )
    {
        fin>>a>>b;

        poz1 = min ( ap[a], ap[b] );
        poz2 = max ( ap[a], ap[b] );

        lv = lg [ poz2 - poz1 ];

        if ( nodniv[ rmq[ lv ][ poz1 ] ] < nodniv [ rmq [ lv ][ poz2 - ( 1 << lv  ) + 1 ] ] )
        {
            fout<<rmq[ lv ][ poz1 ]<<'\n';
        }
        else
        {
            fout<< rmq [ lv ][ poz2 - ( 1 << lv ) + 1  ] <<'\n';
        }

    }

    return 0;

}