Cod sursa(job #2562890)

Utilizator AndreiDeltaBalanici Andrei Daniel AndreiDelta Data 29 februarie 2020 19:35:38
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.44 kb
#include <bits/stdc++.h>
#define Dim 100010
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int N,M,a,b,rmq[4*Dim][30],Euler[4*Dim],cnt,first[Dim],viz[Dim],G[Dim];

vector < int > V[Dim];

void DFS(int nod,int niv)
{
    viz[nod]=1;
    Euler[++cnt]=nod;
    first[nod]=cnt;
    G[nod]=niv;

    for(unsigned int i=0;i<V[nod].size();i++)
    {
        int vecin=V[nod][i];
        if( !viz[vecin] )
        {
            DFS(vecin,niv+1);
            Euler[++cnt]=nod;
        }
    }

    viz[nod]=2;

}

void RMQ()
{
    for(int i=1;i<=cnt;i++) rmq[i][0]=i;

    for(int j=1;j<=log2(cnt);j++)
    for(int i=1; i + ( 1<<j ) -1 <= cnt ;i++ )
    if( G[ Euler [ rmq[i][j-1] ] ] < G[ Euler[ rmq[ i + ( 1 << (j-1) ) ][j-1] ] ] )
    rmq[i][j]=rmq[i][j-1];
    else rmq[i][j]=rmq[ i + ( 1 << (j-1 ) ) ][j-1];
}

int Go(int u,int v)
{
    if( first[u] > first[v] ) swap(u,v);
    int lg=log2( first[v] - first[u] + 1 );

    if( G[ Euler[ rmq[ first[u] ][ lg ] ] ] < G[ Euler[ rmq[ first[v] - (1<<lg) +1 ][lg] ] ] )
    return Euler[ rmq[ first[u] ][lg] ];
    else
    return Euler[ rmq[ first[v] - (1<<lg) + 1 ][lg] ];
}

int main()
{
    f>>N>>M;
    for(int i=1;i<N;i++)
    {
        f>>a;
        V[a].push_back(i+1);
        V[i+1].push_back(a);
    }

    DFS(1,1);
    RMQ();

    for(int i=1;i<=M;i++)
    {
        f>>a>>b;
        g<<Go(a,b)<<'\n';
    }

    return 0;
}