Cod sursa(job #2358781)

Utilizator ZappaManIosif Adrian-Mihai ZappaMan Data 28 februarie 2019 12:50:36
Problema Range minimum query Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.29 kb
#include <stdio.h>

inline int min(int a, int b) {
   return a < b ? a : b;
}

const int NMAX = 100005;
const int MMAX = 1000005;
const int LOGN = 30;

int arr[NMAX];
int dp[NMAX][LOGN];
int N,M;

void create_rmq() {
   int logn = 0;
   int p = 1;
   while ((p << 1) <= N) {
      p = p << 1;
      logn++;
   }

   for (int i = 0; i < N; ++i) {
      dp[i][0] = arr[i];
   }

   for (int l = 1; l <= logn; ++l) {
      int p = (1 << l);
      int pp = (1 << (l-1));
      for (int i = 0; i + pp < N; ++i) {
         dp[i][l] = min(dp[i][l-1], dp[i+pp][l-1]);
      }
   }
}

int rmq(int l, int r) {
   int dist = r - l + 1;
   int logdist = 0;
   int p = 1;

   while ((p << 1) <= dist) {
      p = p << 1;
      logdist++;
   }
   int pp = 1;
   int logdiff = 0;
   int diff = dist - (1 << logdist);
   if (diff == 0) {
      pp = 0;
   } else {
      while ((pp << 1) <= diff) {
         pp = pp << 1;
         logdiff++;
      }
   }

   return min(dp[l][logdist], dp[l+pp][logdist]);
}

int main() {
   freopen("rmq.in", "r", stdin);
   freopen("rmq.out", "w", stdout);
   scanf("%d %d", &N, &M);
   for (int i = 0; i < N; ++i) {
      scanf("%d",&arr[i]);
   }
   create_rmq();
   for (int i = 0; i < M; ++i) {
      int l, r;
      scanf("%d %d",&l, &r);
      printf("%d\n", rmq(l-1,r-1));
   }
   return 0;
}