Cod sursa(job #2662019)

Utilizator BogdanTicuTicu Bogdan Valeriu BogdanTicu Data 23 octombrie 2020 11:54:35
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.06 kb
#include <bits/stdc++.h>

using namespace std;

ifstream in("lca.in");
ofstream out("lca.out");

int rmq[20][400005],nivel[200005],euler[200005],lg[200005];
int k,n,m,first[100005];
vector<int> graf[100005];

void dfs(int nod,int lvl)
{
	euler[++k]=nod;
	nivel[k]=lvl;
	first[nod]=k;
	for(auto x:graf[nod])
	{
		dfs(x,lvl+1);
		euler[++k]=nod;
		nivel[k]=lvl;
	}
}


void rmqq()
{
	for(int i=2;i<=k;i++)
		lg[i]=lg[i/2]+1;
	for(int i=1;i<=k;i++)
		rmq[0][i]=i;
	for(int i=1;(1<<i)<k;i++)
		for(int j=1;j<=k-(1<<i);j++)
		{
			int aux=1<<(i-1);
			rmq[i][j]=rmq[i-1][j];
			if(nivel[rmq[i-1][j+aux]]<nivel[rmq[i][j]])
				rmq[i][j]=rmq[i-1][j+aux];
		}
}


int lca(int x,int y)
{
	int diff,sol;
	int a=first[x],b=first[y];
	if(a>b) swap(a,b);
	diff=b-a+1;
	int lgg=lg[diff];
	sol=rmq[lgg][a];
	int z=diff-(1<<lgg);
	if(nivel[sol]>nivel[rmq[lgg][a+z]])
		sol=rmq[lgg][a+z];
	return euler[sol];
}


int main()
{
	in>>n>>m;
	for(int i=2;i<=n;i++)
	{
		int x;
		in>>x;
		graf[x].push_back(i);
	}
	dfs(1,0);
	rmqq();

	while(m--)
	{
		int x,y;
		in>>x>>y;
		out<<lca(x,y)<<"\n";
	}
	return 0;
}