Cod sursa(job #1753073)

Utilizator vasica38Vasile Catana vasica38 Data 5 septembrie 2016 19:38:14
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.23 kb
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#pragma pack(push, 1)
using namespace std;

int n;
int a[20][100123];

vector <int> g[100123];
int lev[100123];
int lg[100123];

void dfs(int x, int k)
{
	lev[x] = k;
	for (int i = 0; i < g[x].size(); ++i)
	{
		dfs(g[x][i], k+1);
	}
}


int lca(int x, int y)
{
	if (lev[x] < lev[y]) swap(x, y);
	int log1=1, log2=1;
	for ( log1 = 1; (1 << log1) < lev[x]; ++log1)
	for ( log2 = 1; (1 << log2) < lev[y]; ++log2)
	for (int k = log1; k >= 0; --k)
	{
		if (lev[x] - (1 << k) >= lev[y])
		{
			x = a[k][x];
		}
	}
	if (x == y) return x;
	for (int k = log2; k >= 0; --k)
	{
		if (a[k][x] && a[k][x] != a[k][y])
		{
			x = a[k][x];
			y = a[k][y];
		}
	}
	return a[0][x];

}

int m;
int main()
{
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);
	scanf("%d%d", &n,&m);
	for (int i = 2; i <= n; ++i)
	{
		scanf("%d", &a[0][i]);
		g[a[0][i]].push_back(i);
	}
	for (int k = 1; (1 << k) <= n; ++k)
	{
		for (int i = 1; i <= n; ++i)
		{
			a[k][i] = a[k - 1][a[k - 1][i]];
		}
	}
	dfs(1, 0);
	while (m--)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		printf("%d\n", lca(x, y));
	}
	return 0;
}