Cod sursa(job #1634039)

Utilizator DiClauDan Claudiu DiClau Data 6 martie 2016 13:12:48
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.17 kb
#include<stdio.h>
using namespace std;
const int N = 100005, P = 18;
int lst[N], vf[N], urm[N], nrm;
bool viz[N];
int poz[N], put[2 * N], log[2 * N];
struct euler
{
    int ap, depth;
};
int ct = 0;
euler v[2 * N], mat[P][2 * N];
void adauga (int x, int y)
{
    vf[++nrm] = y;
    urm[nrm] = lst[x];
    lst[x] = nrm;
}
void dfs (int depth, int x)
{
    int y, p;
    p = lst[x];
    if (viz[x] == false)
        poz[x] = ct + 1;
    viz[x] = true;
    v[++ct].ap = x;
    v[ct].depth = depth;
    while (p != 0)
    {
        y = vf[p];
        if (viz[y] == false)
        {
            dfs (depth + 1, y);
            v[++ct].ap = x;
            v[ct].depth = depth;
        }
        p = urm[p];
    }
}
int precalculare ()
{
    int i, p = 1, c = 0;
    for (i = 1; i <= ct; i++)
    {
        if ((p << 1) <= i)
        {
            p <<= 1;
            ++c;
        }
        put[i] = p;
        log[i] = c;
    }
    p = 1;
    c = 0;
    while (p <= ct)
    {
        p <<= 1;
        c++;
    }
    for (i = 1; i <= ct; i++)
        mat[0][i] = v[i];

    return c - 1;
}
euler minim (euler a, euler b)
{
    if (a.depth < b.depth)
        return a;
    return b;
}
int main ()
{
    FILE *in, *out;
    in = fopen ("lca.in", "r");
    out = fopen ("lca.out", "w");
    int n, m;
    fscanf (in, "%d%d", &n, &m);
    int i, x;
    for (i = 2; i <= n; i++)
    {
        fscanf (in, "%d", &x);
        adauga (x, i);
        adauga (i, x);
    }
    dfs (0, 1);
    int j, p = precalculare(), k = 1;
    for (i = 1; i <= p; i++)
    {
        for (j = 1; j <= ct; j++)
            if (j + k <= ct)
                mat[i][j] = minim (mat[i - 1][j], mat[i - 1][j + k]);
        k <<= 1;
    }
    int y, aux, putere;
    for (i = 1; i <= m; i++)
    {
        fscanf (in, "%d%d", &x, &y);
        if (poz[x] > poz[y])
        {
            aux = x;
            x = y;
            y = aux;
        }
        x = poz[x];
        y = poz[y];
        putere = put[y - x + 1];
        p = log[y - x + 1];
        fprintf (out, "%d\n", minim (mat[p][x], mat[p][y - putere + 1]).ap);

    }
    return 0;
}