Cod sursa(job #940770)

Utilizator Cosmin1490Balan Radu Cosmin Cosmin1490 Data 17 aprilie 2013 01:28:36
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.15 kb
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <string.h>
#include <iomanip>
#include <time.h>
#include <list>
#include <algorithm>
#include <math.h>
#include <assert.h>
using namespace std;


const string file = "lca";

const string infile = file + ".in";
const string outfile = file + ".out";

vector<vector<int> > G;


int N;
int M;


vector<int> height;
vector<int> minIndex;
vector<int> path;

vector<int> lg;
vector<vector<int> > rmq;

void euler(int n, int l)
{
	path.push_back(n);
	if(minIndex[n] == 0)
	{
		height[n] = l;
		minIndex[n] = path.size() - 1;
	}

	for (vector<int>::iterator itr = G[n].begin();
		 itr != G[n].end();
		 itr++)
	{
		euler(*itr, l+1);
		path.push_back(n);
	}
}

void citire()
{
	ifstream fin(infile.c_str());

	fin >> N >> M;

	G.resize(N+1);
	height.resize(N+1);
	minIndex.resize(N+1);


	for(int i = 2; i <= N ; i++)
	{
		int x;
		fin >> x;
		G[x].push_back(i);
	}

	for(int i = 1; i <= N; i++)
	{
		if(minIndex[i] == 0)
		{
			euler(i, 0);
		}
		
	}

	lg.resize(path.size() + 1);

	lg[2] = 1;

	for(unsigned i = 3; i < path.size() + 1; i++)
	{
		lg[i] = lg[i/2] + 1;
	}

	rmq.resize(lg[path.size()] + 1);
	rmq[0].resize(path.size());

	for(unsigned i = 0; i < path.size(); i++)
	{
		rmq[0][i] = path[i];
	}

	for(int i = 1; i <= lg[path.size()]; i++)
	{
		rmq[i].resize(path.size() - (1 << i));
		
		for(unsigned j = 0; (j  + (1 << i)) < path.size(); j++)
		{
			int min1 = rmq[i-1][j];
			int min2 = rmq[i-1][j + (1 << (i-1))];
			rmq[i][j] = height[min1] < height[min2] ? min1 : min2;
		}
	}


	ofstream fout(outfile.c_str());
	for(int i = 0; i < M; i++)
	{
		int x, y;
		fin >> x >> y;

		x = minIndex[x];
		y = minIndex[y];

		if(x > y) swap(x, y);

		int len = y - x + 1;
		int p = lg[len];
		int toAdd = len - (1 << p);

		int min1 = rmq[p][x];
		int min2 = rmq[p][x + toAdd];
		int ans = height[min1] < height[min2] ? min1 : min2;
		fout << ans << "\n";

	}
	fout.close();

	fin.close();
}



int main()
{
	citire();
}