Cod sursa(job #2121825)

Utilizator vancea.catalincatalin vancea.catalin Data 4 februarie 2018 13:13:22
Problema Lowest Common Ancestor Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.14 kb
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
ifstream fin("lca.in",ios::in);
ifstream buba("buba.in",ios::in);
ofstream fout("lca.out",ios::out);

int n,m,dp[20][100100],niv[100100];
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((1<<idb)!=bit) idb++;
		nod=dp[idb][nod];
	}
	return nod;
}

int main()
{
	int i,j,u,v,a,b,c,d,idb,r,nr=0;
	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=1;i<=m;i++)
	{
		fin>>u>>v;
		c=u; d=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,(1<<(idb-1))); 
			b=salt(v,(1<<(idb-1))); 
			
			if(salt(u,(1<<idb))==salt(v,(1<<idb)) && a!=b) //in intervalul idb,idb-1 tre sa sar musai
			{
				u=a;
				v=b;
			}
			idb--;
		}
		if(u!=v)
			r=dp[0][u];
		else
			r=u;
		fout<<r<<"\n";
	}
	
}