Cod sursa(job #2286901)

Utilizator livliviLivia Magureanu livlivi Data 20 noiembrie 2018 22:51:55
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.24 kb
#include<fstream>
#include<vector>
#define N 100000
#define P 19
using namespace std;

ifstream cin("lca.in");
ofstream cout("lca.out");

vector<int> fii[N + 1];
int nivel[N + 1];

int id[N + 1];
vector<int> rmq[P];

void dfs(int nod = 1){
	id[nod] = rmq[0].size();
	rmq[0].push_back(nod);

	for(int i = 0; i < fii[nod].size(); i ++){
		int now = fii[nod][i];

		nivel[now] = nivel[nod] + 1;
		dfs(now);

		rmq[0].push_back(nod);
	}
}

int merge(int a, int b){
	if (nivel[a] < nivel[b]) return a;
	return b;
}

void mkrmq(){
	for(int i = 1; i < P; i++){
		if ((1 << i) > rmq[0].size()) break;

		for(int j = 0; j < rmq[0].size(); j ++){
			if (j + (1 << i) > rmq[0].size()) break;

			rmq[i].push_back(merge(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]));
		}
	}
}

int query(int a, int b){
	a = id[a];
	b = id[b];
	if (a > b) swap(a, b);

	int p = 0;
	while((1 << p) <= b - a + 1)
		p ++;
	p --;

	//cout << '\n' << p << ' ' << a << ' ' << b << '\n';

	return merge(rmq[p][a], rmq[p][b - (1 << p) + 1]);
}

int main(){
	int n, m;
	cin >> n >> m;

	for(int i = 2; i <= n; i ++){
		int tata;
		cin >> tata;

		fii[tata].push_back(i);
	}

	dfs();
	mkrmq();

	for(int i = 1; i <= m; i ++){
		int a, b;
		cin >> a >> b;

		cout << query(a, b) << '\n';
	}

	return 0;
}