Cod sursa(job #2260389)

Utilizator nicolaefilatNicolae Filat nicolaefilat Data 14 octombrie 2018 22:02:35
Problema Range minimum query Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.38 kb
#include <iostream>
#include <cmath>
#include <fstream>

const int MAXN = 1e5 + 5,MAX_NUMBER = 1e6 + 5,MAX_LOG = log2(MAX_NUMBER);

using namespace std;

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

int dp[MAX_LOG][MAXN],v[MAXN],log_precalc[MAX_NUMBER],n,q;
//dp[i][j] = min pe v[j, j + 2 ^ i]
///i = 0 => min pe v[j, j + 1]
int put;

int main()
{
    in>>n>>q;
    for(int i = 1; i <= n; i++)
        in>>v[i];
    for(int i = 2; i <= n; i++)
        log_precalc[i] = log_precalc[i<<1] + 1;
    put = log_precalc[n];
    for(int j = 2; j <= n; j++)
        dp[0][j - 1] = min(v[j],v[j - 1]);
    dp[0][n] = v[n];

    for(int i = 1; i <= put; i++){
        for(int j = 1; j <= n; j++){
            /// [j,j + 2 ^ i] = [j, j + 2 ^ (i - 1)] U [j + 2 ^ (i - 1), j]
            /// dp[i][j] = dp[i - 1][j] , dp[i - 1][j + 2 ^ (i - 1)]
            if(j + (1<<i) <= n)
                dp[i][j] = min(dp[i - 1][j],dp[i - 1][j + (1<<(i - 1))]);
        }
    }
    for(int test = 1; test <= q; test++){
        int i,j;
        in>>i>>j;
        if(i == j)
            out<<v[i]<<"\n";
        else{
            int lung = j - i,log = log_precalc[lung];
            /// [i,j] = [i, i + 2 ^ log] U [j - 2 ^ log,j]
            /// min[i,j] = dp[log][i] , dp[log][j - 2 ^ log]
            out<<min(dp[log][i],dp[log][j - (1<<log)])<<"\n";
        }
    }
    return 0;
}