Cod sursa(job #760394)

Utilizator matei_cChristescu Matei matei_c Data 21 iunie 2012 11:12:26
Problema Range minimum query Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.4 kb
#include<cstdio>
#include<algorithm>
using namespace std;

#define maxn 100001
#define maxlog 20 

int n,v[maxn] ;
int m[maxlog][maxn] ;
int t,x,y ;
int log[maxn] ;

/*
int rasp(int x,int y)
{
	
	if( x == y )
		return v[x] ;
	int dif = y - x + 1 ;
	
	int log = 1 ;
	int num = 1;
	
	while( num <= dif )
	{
		++ log ;
		num *= 2 ;
	}
	
	num /= 2 ;
	-- log ;
	
	return min ( m[log][ y -  num + 1 ] , rasp(x , y - num + 1 ) ) ;

}
*/

void precalc()
{
	int num = 2 ;
	int lg = 0 ;
	log[1] = 0 ;
	for(int i=2;i<=maxn;++i)
	{
		if( i == num )
		{
			num *= 2 ;
			++ lg ;
		}	
		log[i] = lg ;
	}	
}

int pow(int x,int y)
{
	int r = 1 ; 
	for(int i=1;i<=y;++i)
		r *= x ;
	return r ;
}

int main()
{
	
	freopen("rmq.in","r",stdin);
	freopen("rmq.out","w",stdout);
	
	scanf("%d%d",&n,&t);
	for(int i=1;i<=n;++i)
	{
		scanf("%d",&v[i]);
		m[1][i] = v[i] ;
	}
	
	int pas = 1 ;
	int lin = 2 ;
	while( 1 + pas <= n )
	{
		for(int i=1;i<=n;++i)
		{
			if( i + pas > n )
				m[lin][i] = m[lin-1][i] ;
			else
				m[lin][i] = min ( m[lin-1][i] , m[lin-1][i+pas] ) ;
		}	
		pas *= 2 ;
		++ lin ;
	}	

	precalc() ;
	
	++t ;
	while( -- t )
	{
		scanf("%d%d",&x,&y);
		int dif = y - x  ;
		int val = pow ( 2 , log[dif] ) ;
		int rez = min ( m[ log[dif] + 1 ][x] , m[ log[dif] + 1 ][ y - val + 1 ] ) ;
		printf("%d\n",rez);
	}	
	
	return 0;
	
}