Cod sursa(job #1519500)

Utilizator cristina_borzaCristina Borza cristina_borza Data 7 noiembrie 2015 14:05:05
Problema Lowest Common Ancestor Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.57 kb
#include <fstream>

#define NMAX 100005

using namespace std;

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

int n , nr , ne , m , x , y , tata[NMAX] , poz[NMAX] , vf[2 * NMAX] , urm[2 * NMAX] , lst[NMAX] , e[2 * NMAX] , niv[NMAX] , r[2 * NMAX][30] , lg[NMAX];

void adaug(int x , int y);
void euler(int x);
void rmq();
void query(int x , int y);

int main() {
    f >> n >> m;

    for(int i = 2 ; i <= n ; ++i) {
        f >> tata[i];

        adaug(tata[i] , i);
    }

    euler(1);

    rmq();

    for(int i = 1 ; i <= n ; ++i) {
        int aux = 1;
        while((1 << aux) <= i) {
            ++aux;
        }

        lg[i] = aux - 1;
    }

    for(int i = 1 ; i <= m ; ++i) {
        f >> x >> y;
        if(poz[x] < poz[y])
            query(poz[x] , poz[y]);
        else
            query(poz[y] , poz[x]);
    }
    return 0;
}

void adaug(int x , int y) {
    ++nr;
    vf[nr] = y;
    urm[nr] = lst[x];
    lst[x] = nr;
}

void euler(int x) {
    e[++ne] = x;
    if(poz[x] == 0) {
        poz[x] = ne;
    }

    int p = lst[x] , y;

    niv[x] = 1 + niv[tata[x]];

    while(p) {
        y = vf[p];
        euler(y);
        e[++ne] = x;
        p = urm[p];
    }
}

void rmq() {
    for(int i = 1 ; i <= 2 * n ; ++i) {
        r[i][0] = e[i];
        for(int j = 1 ; (1 << j) <= i ; ++j) {
            r[i][j] = r[i - (1 << (j - 1))][j - 1];
            if(niv[r[i][j - 1]] < niv[r[i][j]]) {
                r[i][j] = r[i][j - 1];
            }
        }
    }
}

void query(int x , int y) {
    int aux = lg[y - x + 1];
    g << min(r[y][aux] , r[x + (1 << aux) - 1][aux]) << '\n';
}