Cod sursa(job #1416639)

Utilizator paunmatei7FMI Paun Matei paunmatei7 Data 8 aprilie 2015 17:10:55
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.65 kb
#include<stdio.h>
#include<vector>
#include<algorithm>

#define NMAX 100007
#define LMAX 20

using namespace std;

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

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

void RMQ(){
    Lg[1] = 1;
    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);
        a = H[a];
        b = H[b];
        if(a > b)
            swap(a, b);
        int l = Lg[b - a + 1] - 1;
        int Number = b + 1 - (1 << l);
        if(L[D[l][a]] < L[D[l][Number]])
            printf("%d\n", E[D[l][a]]);
        else
            printf("%d\n", E[D[l][Number]]);
    }
    return 0;
}