Cod sursa(job #1970853)

Utilizator popescu.octavianPopescu Octavian popescu.octavian Data 19 aprilie 2017 17:34:28
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.37 kb
#include <fstream>
#include <vector>
#include <algorithm>
#define pb push_back
#define NMax 100105
#define LgMax 20

using namespace std;

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

vector<int> G[NMax];
int N, M, i, tata, a, b, k;
int RMQ[4*NMax][LgMax], RE[2*NMax], niv[2*NMax], Lg[2*NMax], first[NMax];

void DFS(int nod, int nivel)
{
    RE[++k]=nod; niv[k]=nivel;
    first[nod]=k;

    for(int i=0; i<G[nod].size(); i++)
    {
        DFS(G[nod][i], nivel+1);

        RE[++k]=nod; niv[k]=nivel;
    }
}

void rmq ()
{
    int i, j;
    for(i=1; i<=k; i++)
    {
        if(i>1) Lg[i]=Lg[i/2]+1;
        RMQ[i][0]=i;
    }

    for(j=1; (1<<j)<=k; j++)
        for(i=1; i+(1<<j)-1<=k; i++)
            if(niv[RMQ[i][j-1]]<=niv[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 LCA(int x, int y)
{
    int a=first[x], b=first[y], sol;
    if(a>b) swap(a,b);
    int lg;
    lg=Lg[b-a+1];
    if(niv[RMQ[a][lg]]<=niv[RMQ[b-(1<<lg)+1][lg]])
        sol=RMQ[a][lg];
        else sol=RMQ[b-(1<<lg)+1][lg];
    return RE[sol];
}
int main()
{
    f>>N>>M;
    for(i=2; i<=N; i++)
    {
        f>>tata;
        G[tata].pb(i);
    }
    DFS(1,0);
    rmq();

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