Cod sursa(job #156283)

Utilizator megabyteBarsan Paul megabyte Data 12 martie 2008 14:19:10
Problema Range minimum query Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.13 kb
#include <stdio.h>
#define INF "rmq.in"
#define OUF "rmq.out"
#define MIN(A,B) ((A<B)?(A):(B))

const int NMAX=100002;
const int LG=20;
const int BIG=2000000;
int n,a[NMAX],rmq[NMAX][LG];
int mlg[NMAX]={0};

void mlg_init()
{
     mlg[0]=-1;
     int i=1,p=0;
     for(i=1;i<=n;++i)
     if(i==(1<<p))
     {
                  mlg[i]=mlg[i-1]+1;
                  ++p;
     }
     else mlg[i]=mlg[i-1];
}

void preproc()
{
     int i,j;

     for(i=0;i<=n;++i)
     for(j=0;j<LG;++j) rmq[i][j]=BIG;
     
     for(i=1;i<=n;++i) rmq[i][0]=a[i];
     
     for(j=1;(1<<j)<=n;++j)
       for(i=1;(i+(1<<j)-1)<=n;++i) rmq[i][j]=MIN(rmq[i][j-1],rmq[i+(1<<(j-1))][j-1]);
}

inline int vmin(int lo,int hi)
{
      int k;
      k=mlg[hi-lo+1];
      return MIN(rmq[lo][k],rmq[hi-(1<<k)+1][k]);
}

int main()
{
	FILE *in,*out;
	in=fopen(INF,"r");
	out=fopen(OUF,"w");
	int i,m,x,y;
	fscanf(in,"%d%d",&n,&m);
	for(i=1;i<=n;++i) fscanf(in,"%d",a+i);
	
	mlg_init();
	preproc();

	for(i=1;i<=m;++i)
	{
		fscanf(in,"%d%d",&x,&y);
		fprintf(out,"%d\n",vmin(x,y));
	}

	fclose(in);fclose(out);
	return 0;
}