Cod sursa(job #1379362)

Utilizator diana97Diana Ghinea diana97 Data 6 martie 2015 17:34:20
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

ifstream f ("lca.in");
ofstream g ("lca.out");

const int NMAX = 100000 + 1;
const int LOGMAX = 18 + 1;

int n, m, nre, e;
int eticheta[NMAX], etichetat[NMAX];
int prima[NMAX], ultima[NMAX];
int log2[2 * NMAX];
int rmq[LOGMAX][2 * NMAX];
vector <int> graf[NMAX];


void citeste() {
    int t;
    f >> n >> m;
    for (int i = 2; i <= n; i++) {
        f >> t;
        graf[t].push_back(i);
    }
}

void liniarizeaza(int nod) {
    eticheta[nod] = ++e;
    etichetat[e] = nod;
    rmq[0][++nre] = e;
    prima[nod] = nre;

    int l = graf[nod].size(), fiu;

    for (int i = 0; i < l; i++) {
        fiu = graf[nod][i];
        if (eticheta[fiu]) continue;
        liniarizeaza(fiu);
        rmq[0][++nre] = eticheta[nod];
    }
}

void precalculeaza() {
    int l;
    for (int i = 2; i <= nre; i++) log2[i] = log2[i / 2] + 1;

    for (int i = 1; (1 << i) <= nre; i++) {
        l = 1 << (i - 1);
        for (int j = 1; j <= nre - (1 << i) + 1; j++)
            rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + 1]);
    }
}

inline int get_lca(int a, int b) {
    int lca, l;
    a = prima[a];
    b = prima[b];
    if (a > b) swap(a, b);
    l = log2[b - a + 1];
    lca = etichetat[min(rmq[l][a], rmq[l][a + l + 1])];
    return lca;
}

void rezolva() {
    int a, b;

    while(m--) {
        f >> a >> b;
        g << get_lca(a, b) << '\n';
    }
}

int main() {
    citeste();
    liniarizeaza(1);
    precalculeaza();
    rezolva();
    return 0;
}