Cod sursa(job #675092)

Utilizator AndreiRSStatescu Andrei Rares AndreiRS Data 7 februarie 2012 10:10:28
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.13 kb
#include <fstream>
#include <vector>
using namespace std;

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

const int dim = 100005, lgm = 19;
int N, M, NE, S[dim], P2[dim], Ap[dim], Au[dim], E[lgm][dim<<1];
vector <int> V[dim];

void init ()
{
	fi >> N >> M;
	for (int i = 2, x; i <= N; i++)
	{
		fi >> x;
		V[x].push_back (i);
	}	
}

void dfs (int n, int k)
{
	S[n] = k;
	E[0][++NE] = n;	
	
	Ap[n] = NE;
	for (int i = 0; i < V[n].size(); i++)
	{
		dfs (V[n][i], k + 1);
		E[0][++NE] = n;
	}
	Au[n] = NE;
}

void prep ()
{
	int i, j;
	for (i = 1; 1<<i <= NE; i++)
		for (j = 1; j + (1<<i) - 1 <= NE; j++)
			if (S[E[i-1][j]] < S[E[i-1][j + (1<<(i-1))]])
				E[i][j] = E[i-1][j];
			else
				E[i][j] = E[i-1][j + (1<<(i-1))];
	for (int i = 2; i <= N<<1; i++)
		P2[i] = P2[i>>1] + 1;
}

int query (int x, int y)
{
	int k = P2[y - x + 1];
	if (S[E[k][x]] < S[E[k][y+1 - (1<<k)]])
		return E[k][x];
	else
		return E[k][y+1 - (1<<k)];
}

int main ()
{
	init ();
	dfs (1, 1);
	prep ();
	
	int x, y;
	while ( M-- )
	{
		fi >> x >> y;
		fo << query (Ap[x], Au[y]) << '\n';
	}
	return 0;
}