Cod sursa(job #2950614)

Utilizator andreipirjol5Andrei Pirjol andreipirjol5 Data 4 decembrie 2022 12:34:59
Problema Range minimum query Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.55 kb
#include <cstdio>
#include <cmath>
#include <iostream>

using namespace std;
FILE *fin, *fout;

int n;
const int NMAX = 1e5;
int v[NMAX + 5], rmq[NMAX + 5][(int)log2(NMAX + 5) + 1];

int lgput(int base, int exp)
{
    int p = base, p1 = 1;

    while(exp)
    {
        if(exp % 2 == 1)
        {
            p1 = 1LL * p * p1;
            exp--;
        }
        else if(exp % 2 == 0)
        {
            p = 1LL * p * p;
            exp /= 2;
        }
    }

    return p1;
}

void make_rmq()
{
    for(int i = 1; i <= log2(n); i++)
    {
        for(int j = 1; j <= n; j++)
        {
            if(j + lgput(2 , i - 1) <= n)
            rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + lgput(2, i - 1)]);
            else rmq[i][j] = rmq[i - 1][j];
        }
    }
}

int query(int left, int right)
{
    if(left == right)
    return v[left];

    int exp_max = log2(right - left);

    return min(rmq[exp_max][left], min(rmq[exp_max][right - lgput(2, exp_max)] , v[right]));
}

int main()
{
    fin = fopen("rmq.in", "r");
    fout = fopen("rmq.out", "w");

    fscanf(fin, "%d", &n);
    int m;
    fscanf(fin, "%d", &m);

    for(int i = 1; i <= n; i++)
        fscanf(fin, "%d", &v[i]);

    for(int i = 1; i <= n; i++)
        rmq[0][i] = v[i];

    make_rmq();

    for(int i = 1; i <= m; i++)
    {
        int left , right;

        fscanf(fin , "%d%d" , &left , &right);

        fprintf(fout , "%d\n" , query(left , right));
    }

    fclose(fin);
    fclose(fout);
    return 0;
}