Cod sursa(job #2121967)

Utilizator vancea.catalincatalin vancea.catalin Data 4 februarie 2018 14:57:35
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.21 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);
       //nivel nod  /tine noduri  /tine nodul cu niv minim
int n,m,niv[100100],euler[200200],rmq[20][200200],f[100100],lg[200200],le;
vector<int> V[100100];

void dfs(int nod,int nivel)
{
	euler[++le]=nod;
	rmq[0][le]=nod;
	f[nod]=le;
	
	niv[nod]=nivel;
	
	for(auto x: V[nod])
	{
		dfs(x,nivel+1);
		euler[++le]=nod;
		rmq[0][le]=nod;
	}
}
int lca(int u,int v)
{
	int dif;
	if(f[u]>f[v]) swap(u,v);
	dif=f[v]-f[u]+1;
	if(niv[rmq[lg[dif]][f[u]]]<niv[rmq[lg[dif]][f[v]-(1<<lg[dif])+1]])
	{
		return rmq[lg[dif]][f[u]];
	}
	else
	{
		return rmq[lg[dif]][f[v]-(1<<lg[dif])+1];
	}
}

int main()
{
	int i,j,t,u,v,lim1,lim2;
	fin>>n>>m;
	for(i=2;i<=n;i++)
	{
		fin>>t;
		V[t].push_back(i);
	}
	dfs(1,1);
	lim1=le;
	
	for(i=0;(1<<i)<=lim1;i++) lg[1<<i]=i;
	for(i=1;i<=le;i++) lg[i]=max(lg[i-1],lg[i]);
	
	for(i=1;i<=lg[le];i++)
	{
		lim2=le-(1<<i)+1;
		for(j=1;j<=lim2;j++)
		{
			rmq[i][j]=rmq[i-1][j];
			
			if(niv[rmq[i][j]]>niv[rmq[i-1][j+(1<<(i-1))]] ) 
				rmq[i][j]=rmq[i-1][j+(1<<(i-1))];
				
		}
	}

	for(i=1;i<=m;i++)
	{
		fin>>u>>v;
		fout<<lca(u,v)<<"\n";
	}
}