Cod sursa(job #2121776)

Utilizator vancea.catalincatalin vancea.catalin Data 4 februarie 2018 12:34:07
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.1 kb
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
fstream fin("lca.in",ios::in), fout("lca.out",ios::out);
int n,m,dp[20][100100],niv[100100],pow[30];
vector<int> V[100100];

void dfs(int nod,int nivel){
	niv[nod]=nivel;
	for(auto x: V[nod]) dfs(x,nivel+1);
}

int salt(int nod, int pas)
{
	int bit,idb=0;
	while(pas!=0)
	{
		bit=(pas-(pas&(pas-1)));
		pas=pas-bit;
		while(pow[idb]!=bit) idb++;
		nod=dp[idb][nod];
	}
	return nod;
}

int main()
{
	int i,j,u,v,a,b,idb;
	fin>>n>>m;
	for(i=2;i<=n;i++)
	{
		fin>>dp[0][i];
		V[dp[0][i]].push_back(i);
	}
	dfs(1,1);
	for(i=1;(1<<i)<=n;i++)
		for(j=1;j<=n;j++)
			dp[i][j]=dp[i-1][dp[i-1][j]];
			
	for(i=0;i<=17;i++) pow[i]=(1<<i); 
	
	
	
	
	for(i=1;i<=m;i++)
	{
		fin>>u>>v;
		if(niv[u]>niv[v]) swap(u,v);
		//acum: niv[u]<=niv[v]
		v=salt(v,niv[v]-niv[u]);
		//acum: niv[u]==niv[v];
		idb=17;
		
		while(idb>0)
		{
			a=salt(u,idb-1); 
			b=salt(v,idb-1);
			if(salt(u,idb)==salt(v,idb) && a!=b) //in intervalul idb,idb-1 tre sa sar musai
			{
				u=a;
				v=b;
			}
			idb--;
		}
		if(u!=v)
			fout<<dp[0][u]<<"\n";
		else
			fout<<u<<"\n";
	}
	
}