Cod sursa(job #1050189)

Utilizator miu_mik93FMI - Paduraru Miruna miu_mik93 Data 8 decembrie 2013 12:46:00
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.89 kb
#include <stdio.h>
#include <iostream>
#include <string>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <queue>
#include <cstdlib>
#include <iomanip>
#include <cmath>
//#include <unordered_map>

using namespace std;

#define NMAX 100001
#define ERROR 0.0001

vector <int> tata[NMAX];
int n, m, euler[2*NMAX], firstAp[2*NMAX], nivel[2*NMAX], k;
int i;

void DFS (int nod, int lev)
{
	euler[++k] = nod;
	nivel[k] = lev;
	firstAp[nod] = k;

	for (vector<int>::iterator it = tata[nod].begin(); it != tata[nod].end(); it++)
	{
		DFS (*it, lev + 1);
		
		euler[++k] = nod;
		nivel[k] = lev;
	}

}

inline int minim(int a, int b)
{
	if ( a < b )
		return a;
	else
		return b;
}

int maximPow[2*NMAX], rmq[30][2*NMAX];
void calc ()
{
	maximPow[1] = 0;
	for (int i = 2; i < 2*NMAX; i++)
		maximPow[i] = maximPow[i/2] + 1;
}

int rmqM (int x, int y)
{
	
	int lim = minim (x, y);
	int lims = x + y - lim;
	int len = lims - lim + 1; 
	int limit = maximPow[len];
	return ( minim ( rmq[limit][lim], rmq[limit][1 + lims - (1<<limit)]) );
}


int main ()
{
	FILE *f = fopen ("lca.in", "r");
	FILE *g = fopen ("lca.out", "w");

	int t;
	//tata[1].push_back (0);
	fscanf (f, "%d %d", &n, &m);
	for (int i = 2; i <= n; i++)
	{
		fscanf (f, "%d", &t);
		tata[t].push_back (i);
	}

	DFS (1, 0);

	int x, y;
	for (int i = 1 ; i <= 2*n - 1; i++)
	{
		rmq[0][i] = euler[i];
	}
	
	calc ();
	
	int limit = maximPow[2*n - 1];
	for (int i = 1; i <= limit; i++)
	{
		for (int j = 1; j <= 2*n + 1; j++)
		{
			rmq[i][j] = minim ( rmq[i-1][j], rmq[i-1][j + (1<<(i-1))] );
		}
	}

	for (int i = 0; i < m; i++)
	{
		fscanf (f, "%d %d", &x, &y);
		fprintf(g, "%d\n", rmqM (firstAp[x], firstAp[y]));
	}


	fclose(f);
	fclose(g);
	return 0;
}