Cod sursa(job #542262)

Utilizator zizou_adyIacov Adrian zizou_ady Data 26 februarie 2011 00:35:22
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.58 kb
#include <vector>
#include <fstream>
#include <cmath>
using namespace std;

#define DIM 100001

ifstream fin("lca.in");
ofstream fout("lca.out");

int t[DIM];
bool s[DIM];

int r[2*DIM-1][18];

vector <vector <int> > G;
int niv_poz[DIM];
int euler[2*DIM-1];

int niv[2*DIM];
int m, n, p;

void Read();
int RMQ(int i,int j);
void DF(int i, int l);
void Solve();

int main()
{
	Read();
	fout.close();
	fin.close();
	return 0;
}

void Read()
{
	fin >> n >> m;
	G.resize(n+1);
	t[1] = 0;
	for (int i = 2; i <= n; ++i)
	{
		fin >> t[i];
		G[t[i]].push_back(i);
	}
	DF(1, 0);
	Solve();
	for (int i = 1; i <= m; ++i)
	{
		int x, y;
		fin >> x >> y;
		if (niv_poz[x] > niv_poz[y])
			fout << RMQ(niv_poz[y], niv_poz[x]) << '\n';
		else
			fout << RMQ(niv_poz[x], niv_poz[y]) << '\n';
	}
}

void DF(int i, int l)
{
	s[i] = true;
	niv[++p] = l;
	euler[p] = i;
	niv_poz[i] = p;
	for (int j = 0; j < G[i].size(); ++j)
	{
		if (!s[G[i][j]])
		{
			s[G[i][j]] = true;
			int k = G[i][j];
			DF(k, l+1);
			niv[++p] = l;
			euler[p] = i;
		}
	}
}

void Solve()
{
	for (int i = 1; i <= 2*n-1; ++i)
		r[i][0] = i;
	for (int j = 1; 1 << j  <= 2*n - 1; ++j)
		for (int i = 1; i + (1 << j) - 1 <= 2*n -1; ++i)
		{
			if (niv[r[i][j - 1]] < niv[r[i + (1 << (j - 1))][j - 1]])
				r[i][j] = r[i][j - 1];
			else
				r[i][j] = r[i + (1 << (j - 1))][j - 1];
		}
}

int RMQ(int i, int j)
{
	int k =(int) log2(j-i + 1);
	if (niv[r[i][k]] <= niv[r[j - (1 << k) + 1][k]])
		return euler[r[i][k]];
	else
		return euler[r[j - (1 << k) + 1][k]];
}