Cod sursa(job #693151)

Utilizator rusu_raduRusu Radu rusu_radu Data 27 februarie 2012 10:09:55
Problema Range minimum query Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.19 kb
#include <cstdio>
#include <cassert>
#define Nmax 100005
#define Lmax 18
#define InFile "rmq.in"
#define OutFile "rmq.out"

using namespace std;

int n, m;
int T[Nmax];
int p2[]={1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144};
int R[Lmax][Nmax];

void preproc();
int solve(int,int);

int main()
{
  int i, x, y;
  assert (freopen (InFile, "r", stdin));
  assert (freopen (OutFile, "w", stdout));
  scanf ("%d %d\n", &n, &m);
  for (i=1; i<=n; i++) scanf ("%d ", &T[i]);
  preproc();
  for (i=1; i<=m; i++)
  {
    scanf ("%d %d\n", &x, &y);
    printf ("%d\n", solve (x, y));
  }
  return 0;
}

void preproc()
{
  int i, k;
  for (i=1; i<=n; i++)
    R[0][i]=i;
  for (k=1; p2[k]<=n; k++)
    for (i=1; i+p2[k]-1<=n; i++)
    {
      if (T[R[k-1][i]]<T[R[k-1][i+p2[k-1]]])
        R[k][i]=R[k-1][i];
      else
        R[k][i]=R[k-1][i+p2[k-1]];
    }
}

int solve (int x, int y)
{
  int i, Min, lg, pz;
  lg=y-x+1;
  pz=0;
  Min=200000;
  for (i=Lmax; i>=0; i--)
    if (lg>=p2[i])
    {
      if (Min>T[R[i][x+pz]])
        Min=T[R[i][x+pz]];
      lg-=p2[i];
      pz+=p2[i];
    }
  return Min;
}