Cod sursa(job #1602562)

Utilizator DanielRusuDaniel Rusu DanielRusu Data 16 februarie 2016 20:21:30
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

#define DIM 10005

vector <vector <int> > Graph;
int VEuler[DIM], FirstApp[DIM], N, Q, x, y, rmq[20][DIM], lungimi[DIM];

void Euler(int nod);

int main() {
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);

    scanf("%d %d\n", &N, &Q);

    Graph.resize(N + 1);

    for(int i = 2; i <= N; ++i) {
        scanf("%d", &x);

        Graph[x].push_back(i);
    }

    Euler(1);

    for(int i = 1; i <= VEuler[0]; ++i) {
        rmq[0][i] = VEuler[i];
        //cout << VEuler[i] << ' ';
    }

    lungimi[1] = 0;

    for(int i = 2; i <= VEuler[0]; ++i) {
        lungimi[i] = lungimi[i / 2] + 1;
    }

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

    while(Q) {
        --Q;

        scanf("%d %d\n", &x, &y);
        x = FirstApp[x];
        y = FirstApp[y];

        int s = y - x + 1 - (1 << (lungimi[y - x + 1]));

        cout << min(rmq[lungimi[y - x + 1]][x], rmq[lungimi[y - x + 1]][x + s]) << '\n';
    }

    return 0;
}

void Euler(int nod) {
    VEuler[++VEuler[0]] = nod;
    FirstApp[nod] = (FirstApp[nod] == 0 ? VEuler[0] : FirstApp[nod]);

    for(unsigned int z = 0; z < Graph[nod].size(); ++z) {
        Euler(Graph[nod][z]);
        VEuler[++VEuler[0]] = nod;
    }

}