Cod sursa(job #2566957)

Utilizator ciutanpCiuta Andrei Calin ciutanp Data 3 martie 2020 14:09:14
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.51 kb
#include<bits/stdc++.h>
using namespace std;

const int NAX = 1e5 + 5;

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

int n, m, k;
vector<int>G[ NAX ];
int fst[ NAX ], h[ 2 * NAX ], l[ 2 * NAX ], lq[ 2 * NAX ], rmq[ 20 ][ 2 * NAX ];

void DFS(int node, int niv)
{
    h[ ++k ] = node;
    l[ k ] = niv;
    fst[ node ] = k;
    for(auto it: G[ node ])
    {
        DFS(it, niv + 1 );
        h[ ++k ] = node;
        l[ k ] = niv;
    }
}

void RMQ()
{
    for(int i = 2 ; i <= k ; ++i)
        lq[ i ] = lq[ i >> 1 ] + 1;
    for(int i = 1 ; i <= k ; ++i)
        rmq[ 0 ][ i ] = i;
    for(int i = 1 ; (1 << i ) < k ; ++i)
    {
        for(int j = 1 ; j <= k - ( 1 << i ); ++j)
        {
            rmq[ i ][ j ] = rmq[ i - 1 ][ j ];
            if( l[ rmq[ i ][ j ] ] > l[ rmq[ i - 1 ][j + (1 << (i - 1 ))]])
               {
                   rmq[ i ][ j ] = rmq[ i - 1 ][j + (1 << (i - 1 ))];
               }
        }
    }
}

int lca(int x, int y)
{
    x = fst[ x ];
    y = fst[ y ];
    if( x > y )
        swap(x, y);
    int ll = lq[ y - x + 1 ];
    int sol = rmq[ ll ][ x ];
    if( l[ sol ] > l[ rmq[ ll ][ y - ( 1 << ll) + 1 ]])
        sol = rmq[ ll ][ y - ( 1 << ll) + 1 ];
    return h[ sol ];
}

int main()
{
    f >> n >> m;
    for(int x, i = 2 ; i <= n ; ++i)
    {
        f >> x;
        G[ x ].push_back( i );
    }
    DFS(1, 0);
    RMQ();
    while( m-- )
    {
        int x, y;
        f >> x >> y;
        g << lca(x, y ) << '\n';
    }
}