Cod sursa(job #1689997)

Utilizator theodor.moroianuTheodor Moroianu theodor.moroianu Data 14 aprilie 2016 17:59:41
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.53 kb
#include <fstream>
#include <vector>
using namespace std;

int nivel[100010], tata[100010], r[100010][19];
ifstream in("lca.in");
vector <int> adia[100010], euler;
int n, m;
void parc_euler(int nod);
void cit();
int prima_aparitie[100010];
int log[300010];

int main()
{
    cit();
    ofstream out("lca.out");
    int a, b;
    while (m--) {
        in >> a >> b;
        a = prima_aparitie[a];
        b = prima_aparitie[b];
        if (a > b) {
            int d = a;
            a = b;
            b = d;
        }
        int l = log[(b - a + 1)];
        if (nivel[r[b][l]] < nivel[r[a + (1 << l)][l]])
            out << r[b][l] << '\n';
        else
            out << r[a + (1 << l)][l] << '\n';
    }
    return 0;
}

void cit() {
    in >> n >> m;
    for (int i = 2; i <= n; i++) {
        in >> tata[i];
        adia[tata[i]].push_back(i);
    }
    parc_euler(1);
    int s = euler.size();
    for (int i = 0; i < s; i++) {
        r[i][0] = euler[i];
    }
    for (int i = 1; i < 19; i++) {
        for (int j = 0; j < s; j++) {
            r[j][i] = r[j][i - 1];
            if (( j - (1 << (i - 1)) >= 0) && nivel[r[j - (1 << (i - 1))][i - 1]] < nivel[r[j][i]]) {
                r[j][i] = r[j - (1 << (i - 1))][i - 1];
            }
        }
    }
    for (int i = 2; i <= n; i++) {
        log[i] = 1 + log[i / 2];
    }
}

void parc_euler(int nod) {
    prima_aparitie[nod] = euler.size();
    nivel[nod] = 1 + nivel[tata[nod]];
    euler.push_back(nod);
    for (auto i : adia[nod]) {
        parc_euler(i);
        euler.push_back(nod);
    }
}