Cod sursa(job #2084693)

Utilizator giotoPopescu Ioan gioto Data 9 decembrie 2017 11:30:58
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.24 kb
#include <bits/stdc++.h>
using namespace std;

int n, m, h;
int d[20][100005], TT[100005], H[100005];
vector <int> F[100005];
inline void dfs(int nod, int lev){
    H[nod] = lev;
    for(auto it : F[nod])
        dfs(it, lev + 1);
}
inline int lca(int x, int y){
    if(H[x] < H[y]) swap(x, y);
    int log1 = 0, log2 = 0;
    for(log1 = 1; (1 << log1) < H[x] ; ++log1) ;
    for(log2 = 1; (1 << log2) < H[y] ; ++log2) ;
    for(int k = log1; k >= 0 ; --k)
        if(H[x] - (1 << k) >= H[y])
            x = d[k][x];
    if(x == y) return x;
    for(int k = log2; k >= 0 ; --k){
        if(d[k][x] && d[k][x] != d[k][y]){
            x = d[k][x];
            y = d[k][y];
        }
    }
    return d[0][x];
}
int main(){
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    scanf("%d%d", &n, &m);
    for(int i = 2; i <= n ; ++i) {
        scanf("%d", &TT[i]);
        F[TT[i]].push_back(i);
        d[0][i] = TT[i];
    }
    dfs(1, 0);
    for(int k = 1; (1 << k) <= n ; ++k)
        for(int i = 1; i <= n ; ++i)
            d[k][i] = d[k - 1][d[k - 1][i]];
    int x, y;
    for(int i = 1; i <= m ; ++i){
        scanf("%d%d", &x, &y);
        printf("%d\n", lca(x, y));
    }
    return 0;
}