Cod sursa(job #1509306)

Utilizator MKLOLDragos Ristache MKLOL Data 23 octombrie 2015 18:19:56
Problema Lowest Common Ancestor Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.2 kb
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<iostream>
#define pb push_back
using namespace std;
int tata[202020][25],N,M, lg[202020], lvl[202020];
vector<int> g[101010];
void dfs(int nod, int lev){
    lvl[nod] = lev;
    for(auto x: g[nod]){
        dfs(x, lev+1);
    }
}

int lca(int x,int y){
    if(lvl[x] < lvl[y]) swap(x,y);

    int log1=1, log2=1;
    for(;(1<<log1) < lvl[x]; ++log1);
    for(;(1<<log2) < lvl[y]; ++log2);

    for(int k = log1; k >= 0; --k){
        if(lvl[x] - (1 << k) >= lvl[y]){
            x = tata[x][k];
        }
    }
    if (x == y) return x;
    for(int k=log2; k>=0 ;--k) {
        if(tata[x][k] && tata[x][k] != tata[y][k]){
            x = tata[x][k];
            y = tata[y][k];
        }
    }
    return tata[x][0];
}

int main(){
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    cin >> N >> M;
    for(int i=2;i<=N;++i){
        cin >> tata[i][0];
        g[tata[i][0]].pb(i);
    }
    dfs(1,0);
    for(int k=1; (1<<k) <= N; ++k){
        for(int i=1;i<=N;++i){
            tata[i][k] = tata[tata[i][k-1]][k-1];
        }
    }
    for(int i=1;i<=M;++i){
        int x,y;
        cin >> x >> y;
        cout << lca(x,y) << "\n";
    }
}