Cod sursa(job #1109428)

Utilizator NikitaUtiuNichita Utiu NikitaUtiu Data 17 februarie 2014 09:47:43
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.48 kb
#include <fstream>
#include <vector>
#include <list>
using namespace std;

int n;
vector <list <int> > muchii;
vector <int> tdesc;
int nivele[200002];
int euler[200002];
int rmq[200001][18];
int lg[200001];

int tmax;
void dfs(int x, int niv) {
	if(tdesc[x] == -1) tdesc[x] = tmax;
	euler[tmax] = x;
	nivele[x] = niv;
	++tmax;
	
	typedef list <int> li;
	typedef li::iterator li_it;
	for(li_it it = muchii[x].begin(); it != muchii[x].end(); ++it) {
		dfs(*it, niv+1);
		euler[++tmax] = x;
	}
	
}

void precalc(void) {
	tdesc.resize(n+1, -1);
	tmax = 0;
	dfs(1, 0);
	
	lg[1] = 0;
	for(int i = 2; i != tmax; ++i)
		lg[i] = lg[i >> 1] + 1;
		
	for(int i = 1; i <= tmax; ++i)
		rmq[i][0] = euler[i];
		
	for(int j = 1; j < lg[tmax]; ++j)
		for(int i = 1; i + (1 << j) - 1 <= tmax; ++i) {
			if(nivele[rmq[i][j-1]] < nivele[rmq[i + (1 << (j-1))][j-1]]) 
				rmq[i][j] = rmq[i][j-1];
			else 
				rmq[i][j] = rmq[i + (1 << (j-1))][j-1];
		}
}

int lca(int x, int y) {
	int a = min(tdesc[x], tdesc[y]);
	int b = max(tdesc[x], tdesc[y]);
	int pow = lg[b - a + 1];
	
	if(nivele[rmq[a][pow]] < nivele[rmq[b - (1 << pow) + 1][pow]])
		return rmq[a][pow];
	else
		return rmq[b - (1 << pow) + 1][pow];
}

int main(void) {
	ifstream fin("lca.in");
	int m;
	fin >> n >> m;
	
	muchii.resize(n+2);
	for(int i = 1; i <= n; ++i) {
		int x; 
		fin >> x;
		muchii[x].push_back(i);
	}
	
	precalc();
	ofstream fout("lca.out");
	for(int i = 0; i < m; ++i) {
		int a, b;
		fin >> a >> b;
		fout << lca(a, b);
	}
	fin.close();
	fout.close();
}