Cod sursa(job #2535947)

Utilizator VladAdrianaVlad Adriana VladAdriana Data 1 februarie 2020 13:07:32
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.27 kb
#include <fstream>
#include <vector>
#define pb push_back
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int uz[100005], n, m,nivk,poz[100005],M[200005][20];
vector <int> L[100005], v,niv;
void Euler(int k)
{
	uz[k] = 1;
	v.pb(k);
	poz[k] = v.size() - 1;
	niv.pb(nivk);
	for (int i = 0; i < L[k].size(); i++)
		if (!uz[L[k][i]])
		{
			nivk++;
			Euler(L[k][i]);
			nivk--;
			v.pb(k);
			niv.pb(nivk);
		}
}
void rmq()
{
	int i, j, k;
	for (i = 0; i < niv.size(); i++)
		M[i][0] = i;
	for (k = 0; (1 << (k + 1)) <= niv.size(); k++);
	for (j = 1; j <= k; j++)
		for (i = 0; i < niv.size()-(1<<j)+1; i++)
			if (niv[M[i][j - 1]] < niv[M[i + (1 << (j - 1))][j - 1]])
				M[i][j] = M[i][j - 1];
			else M[i][j] = M[i + (1 << (j - 1))][j - 1];
}
int lca(int x, int y)
{
	int st = poz[x], dr = poz[y],k;
	if (st > dr) swap(st, dr);
	for (k = 0; (1 << (k + 1)) <= dr-st+1; k++);
	int poz1 = M[st][k], poz2 = M[dr - (1 << k) + 1][k];
	if (niv[poz1] < niv[poz2])
		return v[poz1];
	else return v[poz2];
}
int main()
{
	int i, x,y;
	fin >> n >> m;
	for (i = 2; i <=n; i++)
	{
		fin >> x;
		L[x].pb(i);
		L[i].pb(x);
	}
	Euler(1);
	rmq();
	for (i = 1; i <= m; i++)
	{
		fin >> x >> y;
		fout<<lca(x, y)<<'\n';
	}
	return 0;
}