Cod sursa(job #1970843)

Utilizator popescu.octavianPopescu Octavian popescu.octavian Data 19 aprilie 2017 17:28:33
Problema Lowest Common Ancestor Scor 0
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 F 200010
#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[NMax][LgMax], RE[F], niv[F], log2[F], 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) log2[i]=log2[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=log2[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;
}