Cod sursa(job #178856)

Utilizator toni2007Pripoae Teodor Anton toni2007 Data 15 aprilie 2008 12:18:27
Problema Range minimum query Scor 60
Compilator c Status done
Runda Arhiva educationala Marime 1.11 kb
/*
a[i][j]=min(v[i],v[i+1],...,v[i+2^(j-1))

a[i][0]=v[i]

a[i][j]=min(a[i][j-1],a[i+2^(j-1)][j-1]) pt j>1 si i+2^j<=n+1

min(x,y)=min(a[x][L],a[y-2^(L+1)][L])

L=[lg(y-x+1)]

*/
#include <stdio.h>
#include <stdlib.h>
#define N 100010
#define LOG 17
int a[N][LOG],m,n,v[N],logx[N];
int min(int a,int b){   return (a>b)?b:a;   }
void logar(){
    int i,x=1,y=0;
    for (i=1;i<N;++i){
       if (i<(x<<1))
           logx[i]=y;
       else{
         x<<=1;
         logx[i]=++y;
       }
    }
}
void pre_compute(){
    int i,j;
    for (i=n;i;--i){
       a[i][0]=v[i];
       for (j=1;1+(1<<j)<=n+1;++j){
          a[i][j]=min(a[i][j-1],a[i+(1<<(j-1))][j-1]);
       }
    }
}
void querry(int x,int y){
    int z,L;
    L=logx[y-x+1];
    z=min(a[x][L],a[y-(1<<L)+1][L]);
    printf("%d\n",z);
}
int main(){
    int i,j;
    freopen("rmq.in","r",stdin);
    freopen("rmq.out","w",stdout);
    scanf("%d%d",&n,&m);
    logar();
    for (i=1;i<=n;++i)
       scanf("%d",&v[i]);
    pre_compute();
    while (m--){
      scanf("%d%d",&i,&j);
      querry(i,j);
    }
    exit(0);
}