Cod sursa(job #966503)

Utilizator FlameingoAiordachioaei Marius Flameingo Data 26 iunie 2013 00:27:53
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.44 kb
#include <cstdio>
#include <vector>
using namespace std;

const int DMAX = 100004;
vector <int> A[DMAX], E, D, R[18];
int I[DMAX], l2[DMAX << 1], S;

int _min (const int a, const int b) {

    return D[a] < D[b] ? a : b;

}

void DFS (const int nod, const int dep) {

    R[0].push_back (E.size ());
    E.push_back (nod);
    D.push_back (dep);
    I[nod] = E.size ();
    l2[E.size () + 1] = l2[(E.size () + 1) >> 1] + 1;
    for (int i = 0; i < A[nod].size (); ++i)
        DFS (A[nod][i], dep + 1),
        R[0].push_back (E.size ()),
        E.push_back (nod),
        D.push_back (dep),
        I[nod] = E.size (),
        l2[E.size () + 1] = l2[(E.size () + 1) >> 1] + 1;

}

void RMQ () {

    int i, j, l;
    for (i = 1; (1 << i) <= S; ++i)
        for (j = 0, l = 1 << i - 1; j < S - (1 << i) + 1; ++j)
            R[i].push_back (_min (R[i - 1][j], R[i - 1][j + l]));

}

int QRY (const int l, const int r) {

    const int L = r - l + 1;
    return E[_min (R[l2[L]][l], R[l2[L]][l + L - (1 << l2[L])])];

}

int main() {

    freopen ("lca.in", "r", stdin);
    freopen ("lca.out","w",stdout);

    int N, M, i, a, b;

    scanf ("%d%d", &N, &M);
    for (i = 2; i <= N; ++i)
        scanf ("%d", &a), A[a].push_back (i);

    DFS (1, 0);
    S = D.size ();
    RMQ ();

    while (M--)
        scanf ("%d%d", &a, &b),
        printf ("%d\n", QRY(min (I[a], I[b]) - 1, max (I[a], I[b]) - 1));

}