Cod sursa(job #1911034)

Utilizator B_RazvanBaboiu Razvan B_Razvan Data 7 martie 2017 19:13:10
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.86 kb
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>

using namespace std;

int n, m, vectorTati[100005], dp[100005][20], nrEuler;
vector <pair <int, int> > vEuler;
vector <pair <int, int> >::iterator it;

void parcurgereEuler(int nod, int adancime)
{
    for(int i=1; i<=n; ++i)
    {
        if(vectorTati[i]==nod)
        {
            vEuler.push_back(make_pair(i, adancime+1));
            parcurgereEuler(i, adancime+1);
            vEuler.push_back(make_pair(nod, adancime));
        }
    }

}

void createMatrice()
{
    it=vEuler.begin();
    for(int i=1; i<=vEuler.size(); ++i)
    {
        dp[i][0]=it->second;
        it++;
    }

    int logar=log2(vEuler.size());
    for(int j=1; j<=logar; ++j)
        for(int i=1; i<=vEuler.size(); ++i)
            if(i+(1<<(j-1))<=vEuler.size())
                dp[i][j]=min(dp[i][j-1], dp[i+(1<<(j-1))][j-1]);
            else
                dp[i][j]=dp[i][j-1];
}

void gasireNodMinim(int x, int y)
{
    int pozX=-1, pozY=-1, pozAux=1;
    for(it=vEuler.begin(); it!=vEuler.end(); ++it)
    {
        if(it->first==x && pozX==-1)
            pozX=pozAux;
        if(it->first==y && pozY==-1)
            pozY=pozAux;
        pozAux++;
    }
    int lungime=1+max(pozY, pozX)-min(pozY, pozX);
    int aux=(int) log2(lungime);
    printf("%d\n", min(dp[pozX][aux], dp[pozY-(1<<aux)+1][aux]));
}

void read()
{
    scanf("%d%d", &n, &m);
    for(int i=2; i<=n; ++i)
        scanf("%d", &vectorTati[i]);

    vEuler.push_back(make_pair(1, 0));
    parcurgereEuler(1, 0);
    createMatrice();

    int x, y;
    for(int i=1; i<=m; ++i)
    {
        scanf("%d%d", &x, &y);
        gasireNodMinim(x, y);
    }
}

int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    read();
    return 0;
}