Cod sursa(job #1807983)

Utilizator vlad6001Pintilie Vlad vlad6001 Data 17 noiembrie 2016 10:15:12
Problema Lowest Common Ancestor Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 3.07 kb
#include <fstream>
#include <cmath>
using namespace std;

ifstream cin("lca.in");
ofstream cout("lca.out");

int nr, m, i, tata[100005], cate[100005], nivel[100005], niv, teste, inceput, sfarsit, poz1, poz2, dif, multiplu, yy;
int val[1000][100], j, y, contor, maxim, logaritm;

struct Nod
{
    int valoare;
    Nod* urm;
};
typedef struct Nod* Lista;

Lista x, Lista_curent[1000], Lista_inceput[1000];
int cat, euler[10000], index[10000];

void fa(int i, int niv)
{
    Lista x = Lista_inceput[i];
    cat++;
    euler[cat] = i;
    nivel[cat] = niv;
    if(x != NULL)
    {
        fa(x->valoare, niv+1);
        cat++;
        euler[cat] = i;
        nivel[cat] = niv;
        while(x->urm != NULL)
        {
            x = x->urm;
            fa(x->valoare, niv+1);
            cat++;
            euler[cat] = i;
            nivel[cat] = niv;
        }
    }
}


int main()
{
    cin >> nr >> teste;

    for(i=2; i <= nr; i++)
    {
        cin >> tata[i];

        x = new Nod;
        x->valoare = i;
        x->urm = NULL;
        //Lista_curent[i] = x;

        if(Lista_curent[tata[i]] == NULL)
        {
            Lista_inceput[tata[i]] = x;
            Lista_curent[tata[i]] = x;
        }
        else
        {
            Lista_curent[tata[i]]->urm = x;
            Lista_curent[tata[i]] = Lista_curent[tata[i]]->urm;
        }
    }

    fa(1, 0);

    for(i=1; i <= cat; i++)
    {
        if(index[euler[i]] == 0)
        {
            index[euler[i]] = i;
        }
    }

    for(i=1; i <= cat; i++)
    {
        multiplu = 1;
        for(j=0; multiplu/2 <= cat; j++)
        {
            contor++;

            val[i][j] = 1000000;
            for(y=i; y <= i+multiplu-1 && y <= cat; y++)
            val[i][j] = min(val[i][j], euler[y]);
            multiplu *= 2;
        }
        maxim = j-1;
    }

    /*for(i=1; i <= cat; i++)
    {
        cout << i << " -- ";
        for(j=0; j <= maxim; j++)
        {
            cout << val[i][j] << ' ';
        }
        cout << '\n';
    }*/

    for(i=1; i <= teste; i++)
    {
        cin >> inceput >> sfarsit;
        poz1 = index[inceput];
        poz2 = index[sfarsit];
        if(poz1 > poz2)
        swap(poz1, poz2);

        dif = poz2-poz1+1;
        logaritm = log2(dif);
        multiplu = 1;
        for(yy=1; yy <= logaritm; yy++)
        multiplu *= 2;

        cout << min(val[poz1][logaritm], val[poz2-multiplu+1][logaritm]) << '\n';
    }

    //for(i=1; i <= nr; i++)
    //cout << index[i] << ' ';
    //cout << '\n';

    /*for(i=1; i <= cat; i++)
    cout << euler[i] << ' ';
    cout << '\n';
    for(i=1; i <= cat; i++)
    cout << nivel[i] << ' ';*/

    /*for(i=1; i <= nr; i++)
    {
        cout << i << " -- ";
        x = Lista_inceput[i];
        if(x != NULL)
        {
            cout << x->valoare << ' ';
            while(x->urm != NULL)
            {
                x = x->urm;
                cout << x->valoare << ' ';
            }
        }
        cout << '\n';
    }*/
}