Cod sursa(job #3151764)

Utilizator xDemonstyMatei Haba Ionut xDemonsty Data 22 septembrie 2023 19:35:12
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.01 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream cin("lca.in");
ofstream cout("lca.out");
long long n, q ;

long long depth [ 400005 ];

vector<int> adj [ 400005 ];
vector<int> ans ;
long long firstpoz [ 400005 ];
long long rmq [ 800005] [ 20 ];
long long log2(long long n)
{
    long long k = 0 ;

    while ( 1<<(k + 1) <= n )
    {
        k ++ ;
    }

    return k ;
}
void dfs ( int k )
{

    ans.push_back(k);

    firstpoz [ k ] = ans.size() - 1 ;

    for ( int i = 0 ; i < adj [ k ] .size() ; i ++ )
    {
        int u = adj [ k ] [ i ] ;
        depth [ u ] = depth [ k ] + 1;

        dfs ( u ) ;

        ans.push_back(k);
    }

}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> q;


    for ( int i = 2 ; i <= n ; i ++ )
    {
        long long a ;
        cin >> a ;

        adj [ a ] .push_back(i);
    }

    dfs ( 1 ) ;


    n = ans.size();
    for (int i = 0 ; i < n ; i ++ )
        rmq [ i ] [ 0 ] = ans [ i ] ;

    for ( int i = 1 ; i <= 19 ; i ++ )
    {
        for ( int j = 0 ; j + ( 1 << i )  - 1 < n ; j ++)
        {
            long long a = rmq [ j ] [ i - 1 ] ;
            long long b = rmq [ j + ( 1 << ( i - 1 ) ) ] [ i - 1 ];

            if ( depth[a] < depth[b] )
            {
                rmq [ j ][ i ] = a ;
            }
            else
                rmq [ j ] [ i ] = b ;
        }
    }

    for ( int i = 1 ; i <= q; i ++ )
    {
        long long a, b ;
        cin >> a >> b;
        a = firstpoz [ a ] ;
        b = firstpoz [ b ] ;


        if ( a > b)
            swap ( a, b ) ;

        int len = ( b- a ) + 1;

        long long k = log2 ( len ) ;


        long long d1 = rmq [ a ] [ k ] ;
        long long d2 = rmq [ b  - ( 1 << (k) ) + 1] [ k ] ;

        if ( depth[d1] < depth[d2] )
        {
            cout << d1 << '\n';

        }
        else
            cout << d2 << '\n';
    }


    return 0;
}