Cod sursa(job #1365594)

Utilizator fluture.godlikeGafton Mihnea Alexandru fluture.godlike Data 28 februarie 2015 13:30:59
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.37 kb
#include <stdio.h>
#include <vector>
#define NMAX 100023
FILE *fin, *fout;
int min(int a, int b)
{
	return (a< b)?a:b;
}
int log(int a)
{
	if(a == 1) return 0;
	return 1+ log(a/2);
}
int n, m, poz[NMAX], x, y, tmp, k, d[20][5*NMAX], temp;
std::vector<int> adj[NMAX], parc;
void dfs(int a)
{
	parc.push_back(a);
	int size = adj[a].size();
	int size1 = parc.size();
	poz[a] = size1 - 1;
	for(int i = 0; i< size; i++)
	{
		dfs(adj[a][i]);
		parc.push_back(a);
	}
}
int query(int a, int b)
{
	int sizen = b-a+1;
	sizen = log(sizen);
	return min(d[sizen][a], d[sizen][b - (1<<sizen) + 1]);
}
int main()
{
	fin = freopen("lca.in", "r", stdin);
	fout = freopen("lca.out", "w", stdout);
	scanf("%d%d", &n, &m);
	for(int i = 2; i<= n; i++)
	{
		scanf("%d", &tmp);
		adj[tmp].push_back(i);
	}
	dfs(1);
	int size = parc.size();
	k = log(size);
	for(int i = 0; i<= k; i++)
	{
		for(int j = 0; j< size; j++)
		{
			if(i == 0)
			{
				d[i][j] = parc[j];
			}
			else
			{
				if(j + (1<<i) > size) break;
				d[i][j] = min(d[i-1][j], d[i-1][j + (1<<(i-1))]);
			}
		}
	}
	for(int i = 0; i< m; i++)
	{
		scanf("%d%d", &x, &y);
		if(poz[x] > poz[y])
		{
			temp = x;
			x = y;
			y = temp;
		}
		printf("%d\n", query(poz[x], poz[y]));
	}
	//for(int i = 0; i< size; i++) printf("%d ", parc[i]);printf("\n");
	//for(int i = 1; i<= n; i++) printf("%d ", poz[i]);printf("\n");
	fclose(fin);
	fclose(fout);
	return 0;
}