Cod sursa(job #2566054)

Utilizator 1chiriacOctavian Neculau 1chiriac Data 2 martie 2020 18:33:52
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.44 kb
#include <bits/stdc++.h>

using namespace std;
int n,m,tata[100005],stramosi[27][100005],dist[100005],nod,l[100005];vector <int> arb[100005];queue <int> chestie;
void build_str () {
	for(int i=1;i<=n;++i)	
		stramosi[0][i]=tata[i];
	for(int k=1;(1<<k)<=n;++k)
		for(int i=1;i<=n;++i)
			stramosi[k][i]=stramosi[k-1][stramosi[k-1][i]];
}
void bfs () {
	while(!chestie.empty()) {
		nod=chestie.front();
		for(int i=0;i<(int)arb[nod].size();++i)
			if(dist[arb[nod][i]]==0) {
				chestie.push(arb[nod][i]);
				dist[arb[nod][i]]=dist[nod]+1;
			}
		chestie.pop();
	}
}
int quer (int x, int d) {
	return stramosi[l[d]][x];
}
void cb (int &x, int &y) {
	int step=1;
	for(;(step<<1)<=dist[x];step<<=1);
	for(;step>0;step>>=1)
		if(quer(x,step) != quer(y,step))
			x=quer(x,step),y=quer(y,step);
}
void nivel (int &y, int d) {
	int nr;
	nr=dist[y]-d;
	for(int i=0;nr>0;++i)
		if(((1<<i) & nr)!=0)
			y=stramosi[i][y],nr^=(1<<i);
}
int main () {
	int nr,nod1,nod2;
	freopen("lca.in","r",stdin);
	freopen("lca.out","w",stdout);
	scanf("%d%d", &n, &m);++m;
	for(int i=2;i<=n;++i)
		scanf("%d", &nr),tata[i]=nr,arb[(i)].push_back(nr),arb[nr].push_back(i),l[i]=l[(i>>1)]+1;
	chestie.push(1);dist[1]=1;bfs();tata[1]=1;build_str();
	while(--m) {
		scanf("%d%d", &nod1, &nod2);
		if(dist[nod1]>dist[nod2])
			nivel(nod1,dist[nod2]);
		else
			nivel(nod2,dist[nod1]);
		if(nod1!=nod2) {
			cb(nod1,nod2);
			printf("%d\n", tata[nod1]);
		}
		else
			printf("%d\n", nod1);
	}
	return 0;
}