Cod sursa(job #254090)

Utilizator willliIonel Bratianu willli Data 6 februarie 2009 19:02:18
Problema Range minimum query Scor 40
Compilator c Status done
Runda Arhiva educationala Marime 1.43 kb
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 100001
#define LOGMAX 18
#define in "rmq.in"
#define out "rmq.out"

int a[MAX], M[MAX][LOGMAX], n;

void process_matrix()
{
	unsigned int i,j;

	for (i = n ; i >= 1; i--)	
		for (j = 1 ; i + (1 << j) <= n; j++)
		{
			//printf("i %d i + 1<<j %d\n", i, i + (1<<(j-1)));
			if (a[M[i][j-1]] <= a[M[i + (1<<(j - 1))][j-1]])
				M[i][j] = M[i][j-1];
			else
				M[i][j] = M[i + (1<<(j-1))][j-1];
		}
}

int minim(int x , int y)
{
	int k, m;
	k = log(y - x + 1) / M_LN2;
	
	if (y == x - 1 + (1 << k))
		return M[x][k];
	m = minim(x + (1 << k), y);
	return a[M[x][k]] <= a[m] ? M[x][k] : m;
}

int main()
{
	unsigned int i, z, m, x, y,j;
	FILE *fin, *fout;
	
	if ((fin = fopen(in, "r")) == NULL)
	{
		printf("Eroare \n");
		exit(-1);
	}
	//read dimension of vectors
	fscanf(fin, "%d%d", &n, &m);

	//read the vectors
	for (i = 1; i<=n ; i++)
	{
		fscanf(fin, "%d", &a[i]);
		M[i][0] = i;
	}
	process_matrix();
	/*
	for (i = 1; i <= n; i++)
	{
		for (j = 0; 1 << j <= n; j++)
			printf("%d ", M[i][j]);
		printf("\n");
	}
	printf("\n");
	*/
	fout = fopen(out, "w");
	
	for (i = 0; i < m; i++)
	{
		fscanf(fin, "%d%d", &x, &y);
		//printf("%d %d\n", x, y);
		//printf("x %d y %d z %d x+ 1 <<z %d M[x][z] %d M[x+1..][z-1] %d\n", x, y, z, x + (1<<z), M[x][z], M[x + (1<<z)][z-1]);
		z = minim(x, y);
		//printf("z = %d\n", z);
		fprintf(fout, "%d\n", a[z]);
	}
	fclose(fin);
	fclose(fout);
	return 0;
}