Cod sursa(job #2080790)

Utilizator ice_creamIce Cream ice_cream Data 3 decembrie 2017 15:26:40
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.29 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

const int NMAX = 100000 + 1;
const int PMAX = 18;

int n, m;
int e, ind;

vector <int> graf[NMAX];
int eticheta_nod[NMAX];
int prima_aparitie[NMAX];

int logaritm[NMAX];
int rmq[PMAX][2 * NMAX];

void citeste() {
	f >> n >> m;

	int t;
	for (int i = 2; i <= n; i++) {
		f >> t;
		graf[t].push_back(i);
	}
}

void liniarizeaza(int nod) {
	int eticheta = ++e;
	eticheta_nod[eticheta] = nod;
	prima_aparitie[nod] = ++ind;
	rmq[0][ind] = e;

	int l = graf[nod].size();
	for (int i = 0; i < l; i++) {
		liniarizeaza(graf[nod][i]);
		rmq[0][++ind] = eticheta;
	}
}

void init_rmq() {
	for (int i = 2; i <= ind; i++) logaritm[i] = logaritm[i / 2] + 1;
	for (int p = 1; (1 << p) <= ind; p++) {
		int l = 1 << (p - 1);
		for (int i = 1; i <= ind - l + 1; i++) {
			rmq[p][i] = min(rmq[p - 1][i], rmq[p - 1][i + l]);
		}
	}
}

int query(int a, int b) {
	if (a > b) swap(a, b);
	int l = b - a + 1;
	int p = logaritm[l];
	return min(rmq[p][a], rmq[p][b - (1 << p) + 1]);
}

void rezolva() {
	int a, b;

	for (int i = 1; i <= m; i++) {
		f >> a >> b;
		g << eticheta_nod[query(prima_aparitie[a], prima_aparitie[b])] << '\n';
	}
}

int main() {
	citeste();
	liniarizeaza(1);
	init_rmq();
	rezolva();
	return 0;
}