Cod sursa(job #371240)

Utilizator FlorianFlorian Marcu Florian Data 4 decembrie 2009 15:49:34
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.38 kb
using namespace std;
#include<fstream>
#include<vector>
#define MAX_N 100002
#define lgMAX_N 20
int poz[MAX_N];
int euler[2*MAX_N+1], euler_len, M, N;
int rmq[lgMAX_N][2*MAX_N]; // rmq[i][j] = minimul din intervalul [i, i + 2^j-1]
int niv[MAX_N]; // niv[i] = adancimea nodului euler[i]
vector<int>G[MAX_N];
bool viz[MAX_N];
int lg[2*MAX_N];
void DFS(int x, int n)
{
	if(viz[x]) return;
	viz[x] = 1;
	euler[++euler_len] = x;
	niv[x] = n;
	poz[x] = euler_len;
	unsigned i;
	for(i = 0; i < G[x].size(); ++i)
	{
		DFS(G[x][i], n+1);
		euler[++euler_len] = x;
	}
}
void RANGE()
{
	int i,j;
	for(i = 1; i <= euler_len; ++i)
		rmq[0][i] = euler[i];
	for(j = 1; (1<<j) <= euler_len; ++j)
		for(i = 1; i + (1<<j) <= euler_len; ++i)
		{
			if( niv[rmq[j-1][i]] < niv[rmq[j-1][i + (1<<(j-1))]] )
				rmq[j][i] = rmq[j-1][i];
			else rmq[j][i] = rmq[j-1][i+(1<<(j-1))];
		}
}
int LCA(int x, int y)
{
	int i = min(poz[x], poz[y]), j = max(poz[x], poz[y]);
	int k = lg[j-i+1];
	if(niv[ rmq[k][i] ] <  niv [ rmq[k][j-(1<<k)+1] ]) return rmq[k][i];
	else return rmq[k][j-(1<<k)+1];
}
int main()
{
	ifstream f("lca.in");
	ofstream g("lca.out");
	f>>N; f>>M;
	int i,x,y;
	for(i = 2; i <= 2*N; ++i)
		lg[i] = lg[i/2] + 1;
	for(i = 2; i <= N; ++i)
	{
		f>>x;
		G[x].push_back(i);
	}
	DFS(1,1);
	RANGE();
	while(M--)
	{
		f>>x; f>>y;
		g<<LCA(x,y)<<"\n";
	}
	return 0;
}