Cod sursa(job #2082106)

Utilizator anca.sotirAnca Sotir anca.sotir Data 5 decembrie 2017 18:37:03
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.03 kb
#include <fstream>
#include <bits/stdc++.h>
#define nmax 100002
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int N,M,nrLinA;
vector <int> lista_adiac[nmax],reprez_Euler,nivel,prima_aparitie;
vector <vector <int> > A;
//int A[100][100];
void DF(int x)
{
    reprez_Euler.push_back(x);
    prima_aparitie[x]=reprez_Euler.size()-1;
    for(int i=0;i<lista_adiac[x].size();++i)
        {
            nivel[lista_adiac[x][i]]=nivel[x]+1;
            DF(lista_adiac[x][i]);
            reprez_Euler.push_back(x);
        }
}
void buildRMQ()
{
    int i,p,j=0;
    for(i=0;i<reprez_Euler.size();++i)
        A[0].push_back(reprez_Euler[i]);
        //A[0][i]=reprez_Euler[i];
    for(i=1,p=2;p<=reprez_Euler.size();++i,p*=2)
    {
        //for(j=0;j+p/2<=A[i-1].size();++j)
        for(j=0;j+p<=reprez_Euler.size();++j)
        {
            if(nivel[A[i-1][j]]<nivel[A[i-1][j+p/2]])
                A[i].push_back(A[i-1][j]);
                //A[i][j]=A[i-1][j];
            else //A[i][j]=A[i-1][j+p/2];
                A[i].push_back(A[i-1][j+p/2]);
        }
    }

}
int putere_max_2(int x)
{
    int p=0;
    while(x>1)
    {
        x/=2;
        ++p;
    }
    return p;
}
int gasesteLCA(int x,int y)
{
    int st,dr;
    if(prima_aparitie[x]>prima_aparitie[y])
    {
        st=prima_aparitie[y];
        dr=prima_aparitie[x];
    }
    else
    {
        st=prima_aparitie[x];
        dr=prima_aparitie[y];
    }
    int p=putere_max_2(dr-st+1);
    if(nivel[A[p][st]]<nivel[A[p][dr-(1<<p)+1]])
        return A[p][st];
    else return A[p][dr-(1<<p)+1];
}
int main()
{
    f>>N>>M;
    nivel.resize(N+1);
    prima_aparitie.resize(N+1);
    for(int i=1;i<N;++i)
    {
        int x;
        f>>x;
        lista_adiac[x].push_back(i+1);
    }
    DF(1);

    nrLinA=putere_max_2(reprez_Euler.size());
    A.resize(nrLinA+1);
    buildRMQ();

    for(int i=1;i<=M;++i)
    {
        int x,y;
        f>>x>>y;
        g<<gasesteLCA(x,y)<<'\n';
    }
    return 0;
}