Cod sursa(job #2728397)

Utilizator SergiuS3003Sergiu Stancu Nicolae SergiuS3003 Data 23 martie 2021 10:58:53
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.91 kb
#include <iostream>
#include <fstream>
#include <vector>
#define pb push_back
#define nl '\n'
using namespace std;
ifstream f ( "lca.in" );
ofstream g ( "lca.out" );
const int NMAX = 100001;
int t[NMAX];
vector<int>G[NMAX], Euler, lev;
int firstap[NMAX], nivel[NMAX], p2[2 * NMAX];
int rmq[2 * NMAX][20];
void DFS ( int x, int niv )
{
    nivel[x] = niv;
    Euler.pb ( x );
    firstap[x] = Euler.size();
    lev.pb ( niv );

    for ( auto i : G[x] )
    {
        DFS ( i, niv + 1 );
        Euler.pb ( x );
        lev.pb ( niv );
    }
}
int main()
{
    int N, Q;
    f >> N >> Q;

    for ( int i = 2; i <= N; i++ )
    {
        f >> t[i];
        G[t[i]].pb ( i );
    }

    DFS ( 1, 0 );
    p2[1] = 0;

    for ( int i = 1; i <= 2 * N - 1; i++ )
        rmq[i][0] = i - 1;

    int N2 = 2 * N - 1;

    for ( int i = 2; i <= N2; i++ )
        p2[i] = p2[i / 2] + 1;

    for ( int j = 1; ( 1 << j ) <= N2; j++ )
    {
        int lim = N2 - ( 1 << j ) + 1;

        for ( int i = 1; i <= lim; i++ )
        {
            int p1 = rmq[i][j - 1];
            int p2 = rmq[i + ( 1 << ( j - 1 ) )][j - 1];

            if ( lev[p1] <= lev[p2] )
                rmq[i][j] = p1;
            else rmq[i][j] = p2;
        }
    }

    while ( Q-- )
    {
        int x, y;
        f >> x >> y;
        int cx = firstap[x];
        int cy = firstap[y];

        if ( cx > cy )
            swap ( cx, cy );

        //cout << nivel[x] << ' ' << nivel[y] << ' ' << cx << ' ' << cy << nl;
        int diff = cy - cx + 1, put2 = p2[diff], i2 = cy - ( 1 << put2 ) + 1;
        int p1 = rmq[cx][put2];
        int p2 = rmq[i2][put2];
        int desc = 0;

        if ( lev[p1] <= lev[p2] )
            g << Euler[p1] << nl;
        else g << Euler[p2] << nl;

        //g << nivel[x] + nivel[y] - 2 * min ( rmq[cx][put2], rmq[i2][put2] ) << nl;
    }

    return 0;
}