Cod sursa(job #531892)

Utilizator Gaby_mMititelu Gabriel Gaby_m Data 10 februarie 2011 15:10:13
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.68 kb
#include<cstdio>
#include<vector>
using namespace std;
#define MAXN 100001

int N, M, E;
vector<int> tree[MAXN];
int euler[2*MAXN];
int depth[2*MAXN];
int ap[MAXN];

void buildEuler(int node,int dep) {
	euler[++E] = node; depth[E] = dep;
	if (!ap[node]) ap[node] = E;
	for( int i = 0; i < tree[node].size(); i++) {
		buildEuler(tree[node][i], dep + 1);
		euler[++E] = node; depth[E] = dep;
	}
}

int arb[4*MAXN + 1];
int val, pos;
int left, right;

int min(int a, int b) {
	
	return depth[ap[a]] < depth[ap[b]]? a: b;
}

void update(int nod, int st, int dr) {
	if (st == dr) { 
		arb[nod] = euler[pos]; 
		return;
	}
	int mij = (st + dr) / 2;
	if (pos <= mij) update(nod * 2, st, mij);
	else update(nod * 2 + 1, mij + 1, dr);

	arb[nod] = min (arb[2*nod], arb[2*nod+1]);
}

int arb_min(int nod, int st, int dr) {
	if (left <= st && dr <= right) return arb[nod];

	int mij = (st + dr) / 2;
	int maxleft, maxright;
	maxleft = maxright = INT_MAX;
	if (left <= mij) maxleft = arb_min(nod * 2, st, mij);
	if (mij < right) maxright = arb_min(nod * 2 + 1, mij + 1, dr);

	return min(maxleft, maxright);
}
int main() {
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);
	
	scanf("%d %d", &N, &M);
	int father;
	for (int i = 2; i <= N; i++) {
		scanf("%d", &father);
		tree[father].push_back(i);
	}
	E = 0;	
	buildEuler(1,0);

	for (int i = 1; i <= E; i++) {
		val = depth[i];
		pos = i;
		update(1,1,E);
	}

	int a,b;
	for (int i = 0; i < M; i++) {
		scanf("%d %d", &a, &b);
		left = ap[a];
		right = ap[b];

		if (left > right) {
			int aux = left; left = right; right = aux;
		}

		printf("%d\n", arb_min(1,1,E));
	}
	return 0;
}