Cod sursa(job #403615)

Utilizator ErgoVicol Sergiu Constantin Ergo Data 25 februarie 2010 09:39:08
Problema Range minimum query Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.24 kb
#include <fstream>

#define NMAX 100000
#define LGMAX 10
#define INFI 200000

using namespace std;

ifstream fin("rmq.in");
ofstream fout("rmq.out");

int N, M, Min[NMAX][LGMAX], lg[NMAX], A[NMAX];

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

void Citire(void)
{	
	int i;
	fin >>N >>M;
	for (i = 1; i <= N; i++)
		fin >>A[i];
}

void GenereazaMin(void)
{
	int i, j;
	
	//Intai preprocesam logaritmii
	for (i = 2; i <= N; i++)
		lg[i] = lg[i / 2] + 1;
	
	//Acum Generam Matricea R
	for (i = 1; i <= N; i++)
		Min[i][0] =  A[i];
	
	for (i = 1; i <= N; i++)
		for (j = 1; j <= lg[N]; j++)
			Min[i][j] = INFI;
	
	for (j = 1; (1 << j) <= N; j++)
		for (i = 1; i + (1 << j) - 1 <= N; i++)
		{
			Min[i][j] = minim(Min[i][j-1], Min[i + (1 << (j - 1))][j-1]);
		}
	
}

int QueryRMQ(int s, int d)
{
	if (s < d)
		return minim(Min[s][lg[d- s + 1]], QueryRMQ(s + ( 1 << lg[d- s +1] ), d));
	if (s == d)
		return Min[s][0];
	if (s > d) return INFI;
}

void Rezolva()
{
	int a, b, i;
	
	for (i = 1; i <= M; i++)
	{
		fin >>a >>b;
		fout <<QueryRMQ(a, b) <<'\n';
	}

	fin.close();
	fout.close();
}

int main()
{
	Citire();
	
	GenereazaMin();
	
	Rezolva();

	return 0;
}