Cod sursa(job #1414353)

Utilizator darrenRares Buhai darren Data 2 aprilie 2015 15:49:00
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.28 kb
#include <cstring>
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

int N, M;
int Log[200002];
int RMQ[18][200002];
int niv[100002], in[100002], nod[200002];
vector<int> V[100002];

void Dfs(int x)
{
	nod[++nod[0]] = x;
	in[x] = nod[0];
	
	for (auto nd : V[x])
		if (!in[nd])
		{
			niv[nd] = niv[x] + 1;
			
			Dfs(nd);
			nod[++nod[0]] = x;
		}
}

int main()
{
	ifstream fin("lca.in");
	ofstream fout("lca.out");
	
	for (int i = 2; i <= 200000; ++i)
		Log[i] = Log[i / 2] + 1;
	
	fin >> N >> M;
	for (int i = 2, father; i <= N; ++i)
	{
		fin >> father;
		V[father].push_back(i);
	}
	
	Dfs(1);
	
	for (int i = 1; i <= nod[0]; ++i)
		RMQ[0][i] = nod[i];
	for (int i = 1; (1 << i) <= nod[0]; ++i)
		for (int j = 1; j <= nod[0]; ++j)
		{
			RMQ[i][j] = RMQ[i - 1][j];
			if (j + (1 << (i - 1)) <= nod[0] && niv[RMQ[i - 1][j + (1 << (i - 1))]] < niv[RMQ[i][j]])
				RMQ[i][j] = RMQ[i - 1][j + (1 << (i - 1))];
		}
	
	for (int i = 1, nod1, nod2; i <= M; ++i)
	{
		fin >> nod1 >> nod2;
		
		if (in[nod1] > in[nod2])
			swap(nod1, nod2);
		
		int k = Log[in[nod2] - in[nod1] + 1];
		if (niv[RMQ[k][in[nod1]]] < niv[RMQ[k][in[nod2] - (1 << k) + 1]])
			fout << RMQ[k][in[nod1]] << '\n';
		else
			fout << RMQ[k][in[nod2] - (1 << k) + 1] << '\n';
	}
	
	fin.close();
	fout.close();
}