Cod sursa(job #2587039)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 21 martie 2020 22:03:09
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.34 kb
#include <cstdio>
#include <vector>

using namespace std;

vector<vector<int>> DP;
// DP[i][j] = min(val[j..j+2^i-1])
// DP[0][j] = min(val[j..j+2^0-1]) = val[j]
// DP[i][j] = min(min(val[j         .. j+2^(i-1)-1]),
//                min(val[j+2^(i-1) .. j+2^(i-1)+2^(i-1)-1]))
//          = min(DP[i-1][j], DP[i-1][j + (1<<(i-1))])
vector<int> logs;

int rangeSize(int left, int right)
{
  return right - left + 1;
}

void computeLogs(int N)
{
  logs.resize(N + 1);
  logs[1] = 0;
  for(int i = 2; i <= N; ++i)
    logs[i] = logs[i/2] + 1;
}

void buildRMQ(int N)
{
  int maxLog = logs[rangeSize(1, N)];
  DP.resize(maxLog + 1);
  for (int i = 0; i <= maxLog; ++i)
    DP[i].resize(N);

  for (int i = 0; i < N; ++i)
    scanf("%d", &DP[0][i]);
  for (int i = 1; i <= maxLog; ++i) {
    int stepSize = (1<<(i-1));
    for (int j = 0; j < N - stepSize; ++j)
	DP[i][j] = min(DP[i-1][j], DP[i-1][j + (1<<(i-1))]);
  }
}

int query(int left, int right)
{
  int stepSize = logs[rangeSize(left,right)];
  return min(DP[stepSize][left],
	     DP[stepSize][right - (1<<stepSize) + 1]);
}

int main()
{
  freopen("rmq.in", "r", stdin);
  freopen("rmq.out", "w", stdout);

  int N, M;
  scanf("%d%d", &N, &M);

  computeLogs(N);
  buildRMQ(N);

  for (int i = 0; i < M; ++i) {
    int l, r;
    scanf("%d%d", &l, &r);
    --l; --r;
    printf("%d\n", query(l, r));
  }
  
  return 0;
}