Cod sursa(job #1910141)

Utilizator misu007Pogonaru Mihai misu007 Data 7 martie 2017 15:46:26
Problema Lowest Common Ancestor Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.42 kb
#include <iostream>
#include <cstdio>
#include <algorithm>

#define NMAX 100001

using namespace std;

unsigned n, m, maxH = 0;
unsigned T[NMAX], Tsqrt[NMAX], H[NMAX];

unsigned lcaSQRT(unsigned i, unsigned j) {
    while (Tsqrt[i] != Tsqrt[j]) {
        if (H[i] > H[j]) {
            i = Tsqrt[i];
        } else {
            j = Tsqrt[j];
        }
    }
    while (i != j) {
        if (H[i] > H[j]) {
            i = T[i];
        } else {
            j = T[j];
        }
    }
    return i + 1;
}

void solveSQRT() {
    unsigned i, j;
    while (m--) {
        cin >> i >> j;
        cout << lcaSQRT(i - 1, j - 1) << '\n';
    }
}

void preprocessSQRT() {
    unsigned impartire = (int) sqrt(maxH);
    for (unsigned i = 0; i < n; ++i) {
        unsigned lev = H[i] / impartire;
        unsigned tatal = T[i];
        lev = lev < 1 ? lev : lev - 1;
        while (H[tatal] / impartire != lev) {
            tatal = T[tatal];
        }
        Tsqrt[i] = tatal;
    }
}

void read() {
    unsigned tatal;
    cin >> n >> m;
    T[0] = 0;
    H[0] = 0;
    for (unsigned i = 1; i < n; ++i) {
        cin >> tatal;
        --tatal;
        T[i] = tatal;
        H[i] = H[tatal] + 1;
        maxH = max(maxH, H[i]);
    }
}

int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    read();
    preprocessSQRT();
    solveSQRT();
    return 0;
}