Cod sursa(job #2313363)

Utilizator Vlad3108Tir Vlad Ioan Vlad3108 Data 6 ianuarie 2019 18:54:25
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.09 kb
#include <bits/stdc++.h>
using namespace std;
#define LMAX 100001
int n,m;
int T[20][LMAX],Niv[LMAX];
vector<int> G[LMAX];
void CitirePrecalc(){
    scanf("%d %d",&n,&m);
    for(int i=2;i<=n;++i){
        scanf("%d",&T[0][i]);
        G[T[0][i]].push_back(i);
    }
	for(int k=1;(1<<k)<=n;++k)
		for(int i=1;i<=n;++i)
			T[k][i]=T[k-1][T[k-1][i]];
}
void dfs(int nod,int niv){
    Niv[nod]=niv;
    for(auto it : G[nod])
        dfs(it,niv+1);
}
int lca(int x,int y){
    if(Niv[x]<Niv[y])
        swap(x,y);
    int log1, log2;
	for(log1=1;(1<<log1)<Niv[x];++log1);
	for(log2=1;(1<<log2)<Niv[y];++log2);
	for(int k=log1;k>=0;--k)
        if(Niv[x]-(1<<k)>=Niv[y])
            x=T[k][x];
    if(x==y) return x;
    for(int k=log2;k>=0;--k)
		if(T[k][x]&&T[k][x]!=T[k][y]){
			x=T[k][x];
			y=T[k][y];
		}
    return T[0][x];
}
int main(){
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    CitirePrecalc();
    dfs(1,0);
    for(int i=1;i<=m;++i){
        int x,y;
        scanf("%d %d",&x,&y);
        printf("%d\n",lca(x,y));
    }
	return 0;
}