Cod sursa(job #1659610)

Utilizator AlexandraaaaMereu Alexandra Alexandraaaa Data 22 martie 2016 13:20:16
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.47 kb
#include <iostream>
#include <algorithm>
#include <vector>
#include <fstream>
#include <string>
#define maxN 100000 + 5

using namespace std;

int Min[30][4*maxN], First[maxN], H[maxN];
int n, poz;
vector<int> F[maxN];


int log(int n){
	int a = 0, b = 1;
	while ((b << 1) <= n){
		a++;
		b <<= 1;
	}
	return a;
}

int abs(int x){
	if (x < 0)
		return -x;
	return x;
}


void dfs(int i, int lv){
	H[i] = lv;
	Min[0][poz] = i;
	poz++;
	if (!First[i])
		First[i] = poz-1;

	for (int k = 0; k < F[i].size(); ++k){
		dfs(F[i][k], lv + 1);

		Min[0][poz] = i;
		poz++;
	}
}

void rmqMatr(){
	int lim = log(poz);
	for (int i = 1; i <= lim; ++i){
		int x = 1 << i;
		int y = 1 << (i - 1);

		for (int j = 1; j + x <= poz; ++j){
			int a, b;
			a = Min[i - 1][j];
			b = Min[i - 1][j + y];

			if (H[a] < H[b])
				Min[i][j] = a;
			else
				Min[i][j] = b;
		}
	}
}

int query(int x, int y){
	int a, b, c;
	a = First[x];
	b = First[y];
	if (b < a)
		swap(a, b);

	c = log(b-a+1);

	a = Min[c][a];
	b = Min[c][b - (1 << c) + 1];
	if (H[a] < H[b])
		return a;
	return b;
}

int main()
{
	ifstream f("lca.in");
	ofstream g("lca.out");

	int m;

	f >> n >> m;
	poz = 1;
	for (int i = 2; i <= n; ++i){
		int x;
		f >> x;
		F[x].push_back(i);
	}

	dfs(1, 0);
	poz--;
	rmqMatr();

	for (int k = 0; k < m; ++k){
		int x, y;
		f >> x >> y;
		g << query(x, y) << "\n";
	}

	f.close();
	g.close();

	return 0;
}