Cod sursa(job #600216)

Utilizator dspMihaiDespotovici Mihai dspMihai Data 30 iunie 2011 20:36:51
Problema Range minimum query Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
#include <stdio.h>
#include <math.h>
#define MAX 100001
using namespace std;

long maxj,i,j,N,Mnr,sir[MAX],M[MAX][317];

int power (int x, int p)
{
	int rez=1;
	for (; p>=1; p--) rez*=x;
	return rez;
}
int power2 (int p)
{
	int rez=1;
	for (; p>=2; p-=2) rez*=4;
	for (; p>=1; p--) rez*=2;
	return rez;
}

int logaritm2 (long x)
{
	int rez=0;
	while (power2(rez+1)<=x) rez++;
	return rez;
}
int minsir (int x, int y)
{
	if (x==0) return y;
	if (y==0) return x;
	if (sir[x]<sir[y]) return x;
	else return y;
}

int RMQ (long x, long y)
{
	long k=logaritm2(y-x+1); //printf("(%d,%d)", x,k);
	return sir[minsir(M[x][k],M[y-power2(k)+1][k])];
}
int main ()
{
	freopen("rmq.in", "r", stdin);
	freopen("rmq.out", "w", stdout);
	scanf("%d %d", &N, &Mnr);
	for (i=1; i<=N; i++) {scanf("%d", &sir[i]); M[i][0]=i;}
	maxj=logaritm2(N);
	//printf("%d\n", maxj);
	for (j=1; j<=maxj; j++)
		for (i=1; i+power2(j)-1<=N; i++)
		{
			M[i][j]=minsir(M[i][j-1], M[i+power2(j-1)][j-1]);
			//printf("(%d %d)= (%d %d)-%d, (%d %d)-%d\n",i,j,i,j-1,sir[M[i][j-1]],i+power2(j-1),j-1,sir[M[i+power2(j-1)][j-1]]);
		}
	for (; Mnr>=1; Mnr--)
	{
		scanf("%d %d", &i,&j);
		printf("%d\n", RMQ(i,j));
	}		
		
		
	//for (i=1; i<=N; i++, printf("\n"))
		//for (j=0; j<=N; j++) printf("%d ", M[i][j]);
	return 0;
}