Cod sursa(job #1413795)

Utilizator FlameingoAiordachioaei Marius Flameingo Data 2 aprilie 2015 09:01:58
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
#include <cstdio>
#include <bitset>
#include <algorithm>
#include <vector>
using namespace std;

const int NMAX = 100003;

vector <int> A[NMAX];
bitset <NMAX> check;
int depth[NMAX], e, rmq[19][NMAX * 2 + 1], lg[NMAX * 2 + 1], f[NMAX];

void DFS (const int &node) {

    check[node] = 1;
    rmq[0][++e] = node;
    f[node] = e;
    for (vector <int> :: iterator i = A[node].begin (); i != A[node].end (); ++i) {
        if (!check[*i]) {
            depth[*i] = depth[node] + 1;
            DFS (*i);
            rmq[0][++e] = node;
        }
    }

}

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

    if (depth[a] < depth[b])
        return a;
    return b;

}

void make_rmq () {

    int i, j, k = 1;
    lg[1] = 0;
    for (i = 2; i <= e; ++i)
        lg[i] = lg[i / 2] + 1;
    for (i = 1; e > k; ++i) {
        for (j = 1; j <= e - k; ++j)
            rmq[i][j] = _min (rmq[i - 1][j], rmq[i - 1][j + k]);
        k <<= 1;
    }

}

inline int rmq_query (const int &a, const int &b) {

    int l = b - a + 1;
    return _min (rmq[lg[l]][a], rmq[lg[l]][b - (1 << lg[l]) + 1]);

}

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 = 1; i < N; ++i) {
        scanf ("%d", &a);
        A[i + 1].push_back (a);
        A[a].push_back (i + 1);
    }
    DFS (1);
    make_rmq ();
    while (M--) {
        scanf ("%d%d", &a, &b);
        printf ("%d\n", rmq_query (min (f[a], f[b]), max (f[a], f[b])));
    }

}