Cod sursa(job #2692547)

Utilizator GrizzyProblemSolver79cNot telling GrizzyProblemSolver79c Data 2 ianuarie 2021 23:58:08
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.43 kb
#include <bits/stdc++.h>

using namespace std;

int const NMAX = 1e5;
int const POWERMAX = 20;

ifstream in("rmq.in");
ofstream out("rmq.out");

int dp[1 + NMAX][1 + POWERMAX];
//dp[i][j] = the index that has the minimum in the interval i..i+(1<<j) - 1

int logb2[1 + NMAX];
int powb2[1 + NMAX]; //powb2[i] is rounding i down to a power 2; powb2[5] = 4

int n, nquery;
int a[1 + NMAX];

void init() {
  logb2[1] = 0;
  powb2[1] = 1;
  for(int i = 2; i <= n; i++) {
    if(i == powb2[i-1] * 2) {
      logb2[i] = logb2[i-1] + 1;
      powb2[i] = i;
    } else {
      logb2[i] = logb2[i-1];
      powb2[i] = powb2[i-1];
    }
  }
}

void computedp() {
  for(int i = 1; i <= n; i++) {
    dp[i][0] = i;
  }
  for(int j = 1; j <= logb2[n]; j++) {
    for(int i = 1; i + (1<<j) - 1 <= n; i++) {
      int indexFh = dp[i][j-1];
      int indexSh = dp[i + (1<<(j-1))][j-1];
      if(a[indexFh] < a[indexSh]) {
        dp[i][j] = indexFh;
      } else {
        dp[i][j] = indexSh;
      }
    }
  }
}

int main() {
  in >> n >> nquery;
  for(int i = 1; i <= n; i++) {
    in >> a[i];
  }
  init();
  computedp();
  for(int i=1; i<=nquery; i++) {
    int from, to;
    in >> from >> to;
    int x = to - from + 1;
    int ans = min(a[dp[from][logb2[x]]], a[dp[to-powb2[x]+1][logb2[x]]]);
    //logb2[x] in the second parameter of the RMQ dp indicates a segment of length powb2[x]
    out << ans << "\n";
  }
}