Cod sursa(job #760593)

Utilizator Theorytheo .c Theory Data 22 iunie 2012 10:37:52
Problema Range minimum query Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.28 kb
#include<fstream>
#define nmax 100008
#define ll long long
#define lgnmax 18
#define MIN(a,b) (a > b ? b: a)
using namespace std;
ifstream fin("rmq.in");
ofstream fout("rmq.out");

long long  N, A[nmax] , RMQ[lgnmax][nmax],lg[nmax];
//R[i][j] = minimul din intervalul [j, j + 2 ^i]
void lgg()
{
    lg[1] = 0;
    for(int i = 2; i <= N ;i++)
        lg[i]= lg[i/2] + 1;

}
void build()
{
    lgg();
    for(int i = 1; i <= N; i++)
        RMQ[0][i]  = A[i];
    for(int i = 1 ; (1<<i) <= N; i++)
        for(int j = 1 ; j <=N - (1<<i) + 1; j++)
        {
            ll le = 1<<(i - 1);
            RMQ[i][j] = MIN(RMQ[i - 1][j], RMQ[i - 1][j + le]);//minimul dintre porima si a doua jumatate,
          // fout <<RMQ[i][j] <<" " ;
        }
}

void read()
{
    int M, x, y;

    fin >>N >>M;
    for(int i = 1 ;i <= N; i++)
        fin >>A[i];
        build();
    for(int i = 1 ;i <= M; i++)
    {
        fin >>x >>y;
        ll dif = y -x + 1; //lungimea intervalului
        ll k = lg[dif]; //cea mai mare  putere a lui 2 care intra in lungime(interval)
        ll sh = dif - (1<<k); //ce nu putea acoperi puterea lui 2
        fout <<MIN(RMQ[k][x], RMQ[k][sh + x]) <<'\n' ;

    }

}
int main()
{
    read();
    fin.close();
    return 0;
}