Cod sursa(job #2470155)

Utilizator XsoundCristian-Ioan Roman Xsound Data 8 octombrie 2019 19:34:15
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.02 kb
#include <bits/stdc++.h>
#define Nmax 100005
#define Dmax 17
using namespace std;

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

struct graf
{
    vector < int > v;
};

graf g[Nmax];


int P[Nmax][Dmax];
int H[Nmax], T[Nmax];

int n,q,lvl;

int lca ( int i1, int i2 );
int rmq_aplicat ( int i1, int i2);
void nivelare ( int &i1, int i2 );

void citire ();
void preprocess ();
void dfs_euclid ( int x );

int main()
{
    citire();
    return 0;
}

int rmq_aplicat ( int i1, int i2)
{

    int h= log2(H[i1]);

     for (; h>=0; h--)
        if( P[i1][h]!=-1 && P[i1][h]!=P[i2][h] )
        {
            i1 = P[i1][h];
            i2 = P[i2][h];
        }

        return T[i1];
}

void nivelare( int &i1, int i2 )
{
    int h = log2 (H[i1]);

    for (; h>=0; h--)
        if ( H[i1] - (1<<h)>= H[i2] )
            i1= P[i1][h];
}

int lca ( int i1, int i2 )
{
    if ( H[i1] == H[i2] )
        return rmq_aplicat(i1,i2);

    else
        nivelare(i1,i2);

    if ( i1 == i2 )
        return i1;

    return rmq_aplicat(i1,i2);
}

void citire()
{
    int x, i1, i2;

    fin >> n >> q;

    for ( int i = 1; i < n ; i++ )
    {
        fin >> x;

        g[x-1].v.push_back(i);

        T[i] = x-1;
    }

    lvl = -1;
    dfs_euclid( 0 );

    preprocess();

    for ( int i = 1 ; i <= q; i++ )
    {
        fin >> i1 >> i2;

        fout << lca (i1-1, i2-1) +1 << '\n' ;
    }
}

void preprocess()
{
    int h = log2 ( n ) ;

    for ( int i = 0 ; i < n; i++ )
        for ( int j = 0 ; j <= h ; j++)
            P[i][j] = -1;

    for ( int i = 1 ; i < n; i++ )
        P[i][0] = T[i] ;

    for ( int j = 1; j <=h; j++ )
        for ( int i = 1; i < n; i++ )

            if ( P[i][j-1] != -1 )
                P[i][j] = P[P[i][j-1]][j-1];
            else P[i][j] = -1;
}

void dfs_euclid( int x )
{
    lvl++;
    H[x] = lvl ;

    for ( int i = 0 ; i < g[x].v.size(); i++)
        dfs_euclid(g[x].v[i]);

    lvl--;
}