Cod sursa(job #1442486)

Utilizator MciprianMMciprianM MciprianM Data 25 mai 2015 17:53:06
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.39 kb

//O(N + M * RMAX)
//RMAX = O(sqrt(N))

#include <fstream>
#include <cstring>

using namespace std;

static const int MAXN = 100009;
static const int LG = 18;
int n;
int dad[LG][MAXN];
int level[MAXN];

int getLevel(int nod)
{
	if(level[nod] == -1)
	{
		level[nod] = getLevel(dad[0][nod]) + 1;
	}
	return level[nod];
}

void compute_dads()
{
	for(int i = 1; i < LG; i++)
	{
		for(int j = 1; j <= n; j++)
		{
			dad[i][j] = dad[i - 1][dad[i - 1][j]];
		}
	}
}

int main()
{
	int m, x, y;
	ifstream f("lca.in");
	ofstream g("lca.out");
	f >> n >> m;
	dad[0][1] = 1;
	for(int i = 2; i <= n; i++)
	{
		f >> dad[0][i];
	}
	memset(level, -1, sizeof(level));
	level[1] = 0;
	for(int i = 2; i <= n; i++)
	{
		level[i] = getLevel(i);
	}
	compute_dads();
	for(int i = 0; i < m; i++)
	{
		f >> x >> y;
		if(level[x] > level[y])
		{
			for(int i = LG - 1; i >= 0; i--)
			{
				if(level[dad[i][x]] >= level[y])
				{
					x = dad[i][x];
				}
			}
		}
		if(level[y] > level[x])
		{
			for(int i = LG - 1; i >= 0; i--)
			{
				if(level[dad[i][y]] >= level[x])
				{
					y = dad[i][y];
				}
			}
		}
		if(x != y)
		{
			for(int i = LG - 1; i >= 0; i--)
			{
				if(dad[i][x] != dad[i][y])
				{
					x = dad[i][x];
					y = dad[i][y];
				}
			}
			x = dad[0][x];
			y = dad[0][y];
		}
		g << x << '\n';
	}
	f.close();
	g.close();
	return 0;
}