Cod sursa(job #1875918)

Utilizator Dan_RadulescuRadulescu Dan Dan_Radulescu Data 11 februarie 2017 19:32:51
Problema Lowest Common Ancestor Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.86 kb
#include<fstream>
#define MAX 100001
#define MAXlg 200010
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

int n, M, i, j, l, a, b, mins, maxs, appear[MAX], nivel[MAXlg], v[MAXlg], indice = 0, lg[MAXlg], m[20][MAX];

struct nod
{
    int inf;
    nod *urm;
}*L[MAX];

void adaugasf(nod *&vf, int val)
{
    nod *q;
    q = new nod;
    q->inf = val;
    q->urm = vf;
    vf = q;
}

void DFS(int k, int lev)
{
    indice++;
    appear[k] = indice;
    nivel[indice] = lev;
    v[indice] = k;
    nod *q;
    q = L[k];
    while (q != 0)
    {
        if (appear[q->inf] == 0) DFS(q->inf, lev + 1);
        indice++;
        nivel[indice] = lev;
        v[indice] = k;
        q = q->urm;
    }
}

int main()
{
    fin>>n>>M;
    for (i = 1; i <= n; i++)
        L[i] = 0;
    for (i = 2; i <= n; i++)
    {
        fin>>j;
        adaugasf(L[j], i);
    }
    DFS(1, 0);

    //RMQ
    lg[1] = 0;
    for (i = 2; i <= n; i++)
        lg[i] = lg[i/2] + 1;

    for (i = 1; i <= indice; i++)
        m[0][i] = i;
    for (j = 1; (1<<j) <= indice; j++)
    {
        i = 1;l = 1<<(j-1);
        while (i + 2*l <= indice + 1)
        {
            if (nivel[m[j-1][i]] < nivel[m[j-1][i+l]]) m[j][i] = m[j-1][i];
            else m[j][i] = m[j-1][i+l];
            i++;
        }
    }

    //solutii
    for (i = 1; i <= M ;i++)
    {
        fin>>a>>b;
        if (appear[a] < appear[b])
        {
            mins = appear[a];
            maxs = appear[b];
        }
        else
        {
            mins = appear[b];
            maxs = appear[a];
        }

        l=lg[maxs-mins+1];

        if (nivel[m[l][mins]] < nivel[m[l][maxs - (1<<l) + 1]]) fout<<v[m[l][mins]]<<'\n';
        else fout<<v[m[l][maxs - (1<<l) + 1]]<<'\n';
    }
    fin.close();
    fout.close();
    return 0;
}