Cod sursa(job #2401645)

Utilizator alexalghisiAlghisi Alessandro Paolo alexalghisi Data 9 aprilie 2019 21:25:58
Problema Lowest Common Ancestor Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.08 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
#include <cstring>

#define DN 100005
#define per pair<int,int>
#define pb push_back
#define next_nod list[nod][i]
#define un unsigned
#define mp make_pair
#define DNN 5*DN
using namespace std;

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

int t[DN],deep[DN],sz,ap[DN]; /// rmq[30][DNN];
vector< int > list[DN];
bitset< DN > viz;
int rmq[21][DNN],val[21][DNN];
/// in rmq[][] retin valoarea minima de pe liniarizarea euler arborelui
/// in nod[][] retin nodul cu aceasta valoare

void dfs(int nod,int down)
{
    viz[nod]=true;
    deep[nod]=down;

    rmq[0][++sz]=deep[nod];
    val[0][sz]=nod;
    ap[nod]=sz; /// prima aparitie

    for(un int i=0;i<list[nod].size();++i){

        if( !viz[ next_nod ] ){

            dfs(next_nod , 1 + down);
            rmq[0][++sz]=deep[nod];
            val[0][sz]=nod;
        }
    }
    return;
}
void gen()
{
    for(int pow=1;pow<=20;++pow)
        for(int i=1; i + (1<<(pow-1)) <= sz ;++i){

            int first_part  = rmq [ pow - 1 ][ i ];
            int second_part = rmq [ pow - 1 ][ i + (1<<(pow-1)) ];
            if( first_part < second_part ){

                rmq[ pow ][ i ] = first_part ;
                val[ pow ][ i ] = val [ pow - 1 ][ i ];
            }
            else{

                rmq[ pow ][ i ] = second_part;
                val[ pow ][ i ] = val[ pow-1 ][ i + (1<<(pow-1))];
            }
        }

}
int solve(int a,int b)
{
    int pow=0;
    a = ap[a]; /// prima pozitie in care apare in euler
    b = ap[b];
    if(a>b)
        swap(a,b);

    for(; a + (1<<pow) <=b ;++pow); if(pow) --pow;

    int left = rmq [ pow ][ a ];
    int right = rmq[ pow ][ b - (1<<pow) + 1];

    if(left<right)
        return val [ pow ][ a ];
    return val[pow][ b - (1<<pow) + 1];

}

int main()
{
    int n,m;
    memset(rmq,0x3f3f3f3f,sizeof(rmq));

    f>>n>>m;
    for(int i=2;i<=n;++i){

        f>>t[i];
        list[ t[i] ].pb( i );
    }
    dfs(1,1);
    gen();

    for(;m--;)
    {
        int a,b;
        f>>a>>b;
        g<<solve(a,b)<<"\n";
    }

    return 0;
}