Cod sursa(job #2445885)

Utilizator andreiomd1Onut Andrei andreiomd1 Data 5 august 2019 21:09:19
Problema Range minimum query Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.82 kb
#include <cstdio>
#include <iostream>

using namespace std;

const int BSIZE = (1 << 16), NMAX = 1e5 + 5;

int pos = BSIZE - 1;
char buff[BSIZE];

int N, M, rmq[20][NMAX], l2[NMAX];

static inline char C ()
{
    ++pos;

    if(pos == BSIZE)
    {
        pos = 0;

        fread(buff, 1, BSIZE, stdin);
    }

    return buff[pos];
}

static inline int I ()
{
    int ans = 0;

    while(1)
    {
        char ch = C();

        if(isdigit(ch))
        {
            ans = (ch - '0');

            break;
        }
    }

    while(1)
    {
        char ch = C();

        if(isdigit(ch))
            ans = ans * 10 + (ch - '0');
        else
            break;
    }

    return ans;
}

static inline void Read ()
{
    N = I();
    M = I();

    for(int i = 1; i <= N; ++i)
        rmq[0][i] = I();

    return;
}

static inline void Precalculation ()
{
    l2[1] = 0;
    for(int i = 2; i <= N; ++i)
        l2[i] = l2[i / 2] + 1;

    for(int i = 1; i <= l2[N]; ++i)
    {
        int p = (1 << i);
        int p2 = (p >> 1);

        for(int j = 1; j <= N - p + 1; ++j)
            rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + p2]);
    }

    return;
}

static inline int Query (int Left, int Right)
{
    if(Left == Right)
        return rmq[0][Left];

    int K = (Right - Left + 1);

    K = l2[K];

    return min(rmq[K][Left], rmq[K][Right - (1 << K) + 1]);
}

static inline void Solve ()
{
    while(M--)
    {
        int Left = I(), Right = I();

        printf("%d\n", Query(Left, Right));
    }

    return;
}

int main()
{
    ios_base :: sync_with_stdio(false);
    cin.tie(NULL);

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

    Read();

    Precalculation();

    Solve();

    return 0;
}