Cod sursa(job #999238)

Utilizator paunmatei7FMI Paun Matei paunmatei7 Data 19 septembrie 2013 18:25:07
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.59 kb
#include<stdio.h>
#include<vector>

#define NMAX 100007
#define LMAX 20

using namespace std;

int E[3 * NMAX], L[3 * NMAX], H[3 * NMAX], n, m, D[LMAX][NMAX], Lg[LMAX];
vector< int > v[NMAX];

inline int min(int a, int b){
    if(a > b)
        return b;
    return a;
}

void RMQ(){
    Lg[1] = 0;
    for(int i = 2; i <= E[0]; ++ i)
        Lg[i] = Lg[i / 2] + 1;
    for(int i = 1; i <= E[0]; ++ i)
        D[0][i] = i;
    for(int i = 1; (1 << i) <= E[0]; ++ i)
        for(int j = 1; j <= E[0] - (1 << i) + 1; ++ j)
            if(L[D[i - 1][j]] < L[D[i - 1][j + (1 << (i - 1))]])
                D[i][j] = D[i - 1][j];
            else
                D[i][j] = D[i - 1][j + (1 << (i - 1))];
}

void DFS(int Nod,int lv){
    E[++ E[0]] = Nod;
    L[E[0]] = lv;
    H[Nod] = E[0];
    for(vector< int > :: iterator it = v[Nod].begin(); it != v[Nod].end(); ++ it){
        DFS(*it , lv + 1);
        E[++ E[0]] = Nod;
        L[E[0]] = lv;
    }
}


int main(){
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    scanf("%d %d", &n , &m);
    for(int i = 2; i <= n; ++ i){
        int a;
        scanf("%d", &a);
        v[a].push_back(i);
    }
    DFS(1, 0);
    RMQ();
    for(int i = 1; i <= m; ++ i){
        int a, b;
        scanf("%d %d", &a, &b);
        if(H[a] > H[b]){
            int l = b;
            a = b;
            b = l;
        }
        int l = Lg[H[b] - H[a] + 1];
        int Number = H[b] - H[a] + 1 - (1 << l);
        if(H[D[l][H[a]]] < H[D[l][H[a] + Number]])
            printf("%d\n", E[D[l][H[a]]]);
        else
            printf("%d\n", E[D[l][H[a] + Number]]);
    }
}