Cod sursa(job #690886)

Utilizator balakraz94abcd efgh balakraz94 Data 26 februarie 2012 00:22:26
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include <cstdio>
#include<algorithm>
#include<vector>
#define infile "lca.in"
#define outfile "lca.out"
#define n_max 100005
#define log_max 18
#define pb push_back
#define FOR(g) \
    for(vector<int>::iterator it=g.begin(); it!=g.end(); ++it)
#define nxt *it
using namespace std;

vector < int > v[n_max];

int Poz[n_max], Niv[2*n_max], Euler[2*n_max], log[2*n_max];

int RMQ[2*n_max][log_max];

int Dim;


void MakeRMQ(int N)
{
	for(int i = 2; i <= N; ++i)
		log[i] = log[i>>1] + 1;
	
	for(int i=1; i<=N; ++i)
		RMQ[i][0] = i;
	
	for(int j = 1; (1<<j) <= N; ++j)
		for(int i = 1; (i + (1<<j) - 1) <= N; ++i)
			if(Niv[RMQ[i][j-1]] < Niv[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];
}


void DFS(int rad, int niv)
{
	Niv[++Dim] = niv;
	Euler[Dim] = rad;
	Poz[rad] = Dim;

	FOR(v[rad])
	{
		DFS(nxt, niv + 1);
		
		Euler[++Dim] = rad;
		Niv[Dim] = niv;
	}
}


int LCA(int x, int y)
{
	int px = Poz[x], py = Poz[y];
	
	if(px > py)
			swap(px, py);
		
	int rez, k = log[py - px +1];
	
	if(Niv[RMQ[px][k]] <= Niv[RMQ[py - (1<<k) + 1][k]])
		rez = RMQ[px][k];
	else
		rez = RMQ[py - (1<<k) + 1][k];
	
	return Euler[rez];
}



int main()
{
	freopen(infile, "r", stdin);
	freopen(outfile, "w", stdout);
	
	int N, M;
	int x, y;
	
	scanf("%d %d", &N, &M);

	for(int i=2;i<=N;i++)
	{
		scanf("%d",&x);
		
		v[x].pb(i);
	}
	
	DFS(1,0);
	
	MakeRMQ(Dim);
	
	while(M--)
	{
		scanf("%d %d", &x, &y);
		
		printf("%d\n", LCA(x,y));
	}
	
	fclose(stdin);
	fclose(stdout);

	return 0;
}