Cod sursa(job #2525414)

Utilizator AndreiDeltaBalanici Andrei Daniel AndreiDelta Data 17 ianuarie 2020 12:20:02
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.41 kb
#include <bits/stdc++.h>
#define Dim 100001
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int rmq[2*Dim][30],x,a,b,lvl[Dim],viz[Dim],Euler[2*Dim],cnt,N,M,first[Dim];
//atentie la facptu ca aven rmq[cnt] nu rmq[n]
vector < int > V[Dim];

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

    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]=Euler[i];

    for(int j=1;j<=log2(cnt);j++)
    for(int i=1;i+ (1<<j) -1 <= cnt;i++)
    {
        if( lvl[rmq[i][j-1]] <= lvl[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 main()
{
    f>>N>>M;
    for(int i=2;i<=N;i++)
    {
        f>>x;
        V[x].push_back(i);
        V[i].push_back(x);
    }
    DFS(1,1);
    RMQ();

    for(int i=1;i<=M;i++)
    {
        f>>a>>b;
        if( first[a] > first[b] ) swap(a,b);
        int lg=log2(first[b]-first[a]+1);

        if( lvl[ rmq[first[a]][lg] ] < lvl[ rmq[first[b]-(1<<lg)+1][lg] ] )
            g<<rmq[first[a]][lg];
        else
            g<<rmq[first[b]-(1<<lg)+1][lg];
        g<<'\n';
    }


    return 0;
}