Cod sursa(job #1602629)

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

using namespace std;

#define DIM 210000

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

void Euler(int nod, int level);

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, 0);

    for(int i = 1; i <= VEuler[0]; ++i) {
        rmq[0][i] = 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); ++j) {
            int l = 1 << (i - 1);
            rmq[i][j] = rmq[i - 1][j];
            if(L[rmq[i - 1][j + l]] < L[rmq[i][j]]) {
                rmq[i][j] = rmq[i - 1][j + l];
            }
        }
    }

    while(Q) {
        --Q;

        scanf("%d %d\n", &x, &y);

        x = FirstApp[x];
        y = FirstApp[y];

        if(x > y) {
            swap(x, y);
        }

        int diff = y - x + 1;
        int l = lungimi[diff];
        int sol = rmq[l][x];
        int sh = diff - (1 << l);
        if(L[sol] > L[rmq[l][x + sh]]) {
            sol = rmq[l][x + sh];
        }

        cout << VEuler[sol] << '\n';
    }

    return 0;
}

void Euler(int nod, int level) {
    VEuler[++VEuler[0]] = nod;
    FirstApp[nod] = VEuler[0];
    L[VEuler[0]] = level;

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