Cod sursa(job #373723)

Utilizator perticas_catalinperticas catalin perticas_catalin Data 14 decembrie 2009 21:42:09
Problema Range minimum query Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.8 kb
#include<iostream>
#include<string>

using namespace std;

#define NM 100005
#define PM 17
#define FOR(i,a,b)for(int i=(a);i<=(b);++i)
#define min(a,b)((a)<(b)?(a):(b))
#define maxbuf 65536

FILE*fin=fopen("rmq.in","r");

int A[NM],RMQ[NM][PM],L[NM],N,M,ind;

char buf[maxbuf];

inline void refbuf()
{
     int ans=fread(buf,1,maxbuf,fin);
     
     if(ans<maxbuf) buf[ans]=0;
     
     ind=0;  
}

inline int readnr()
{
     int ans=0;
     
     one:
         while(ind<maxbuf && !isdigit(buf[ind])) ++ind;
         if(ind==maxbuf)
         {
           refbuf();
           goto one;
         }  
         
     two:
         while(ind<maxbuf && isdigit(buf[ind]))
         {
           ans=ans*10+buf[ind]-'0';
           ++ind;
         }    
         if(ind==maxbuf)
         {
           refbuf();
           goto two;
         }
     return ans;    
}

int main()
{
    refbuf();
    
    int a,b;
    
    //freopen("rmq.in","r",stdin);
    freopen("rmq.out","w",stdout);
    
    N=readnr();
    M=readnr();
    
    FOR(i,1,N)
      A[i]=readnr();
    
    int cat=0,poz=1;
    
    while(poz<N)
    {
      int end=poz+(1<<cat)-1;
      
      while(poz<=N && poz<=end)
      {
        L[poz]=cat;
        ++poz;
      }
      
      ++cat;
    }
    
    /*
    FOR(i,1,N)
      printf("%d ",L[i]);
    */
    
    FOR(i,1,N)
      RMQ[i][0]=A[i];
    
    FOR(l,1,16)
      FOR(i,1,N)
      {
        if(i+(1<<l)-1>N) break;
        
        RMQ[i][l]=min(RMQ[i][l-1],RMQ[i+(1<<(l-1))][l-1]);
      }
      
    FOR(i,1,M)
    {
      a=readnr();
      b=readnr();
      
      int l=L[b-a+1];
      
      int ans=min(RMQ[a][l],RMQ[b-(1<<l)+1][l]);
      
      printf("%d\n",ans);
    }  
    
    return 0;
}