Cod sursa(job #534596)

Utilizator dushmiMihai-Alexandru Dusmanu dushmi Data 15 februarie 2011 21:18:10
Problema Range minimum query Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.16 kb
#include<cstdio>
#include<cmath>
#include<fstream>
using namespace std;
const int N=100005,INF=2000000000;
int logn,n,q,p2[20],minn[N][20];
ifstream f("rmq.in");
void read()
{
    freopen("rmq.out","w",stdout);
    f>>n>>q;
    for(int i=1;i<=n;i++)
        f>>minn[i][0];
}
void pregen()
{
    logn=log2(n);
    p2[0]=1;
    for(int i=1;i<=logn;i++)
        p2[i]=(p2[i-1]<<1);
    for(int i=0;i<=logn;i++)
        minn[0][i]=INF;
}
int minim(int x,int y)
{
    return x<y?x:y;
}
void din()
{
    for(int j=1;j<=logn;j++)
        for(int i=1;i<=n;i++)
            minn[i][j]=minim(minn[i][j-1],minn[i+p2[j-1]][j-1]);
}
int cautb(int val)
{
    int i=0,pas=1<<5;
    for(i=0;pas;pas>>=1)
        if(i+pas<=logn && p2[i+pas]<=val)
            i+=pas;
    return i;
}
int rmq(int x,int y)
{
    int minc=INF,put=0;
    while(x<=y)
    {
        put=cautb(y-x);
        minc=minim(minc,minn[x][put]);
        x=x+p2[put];
    }
    return minc;
}
int main()
{
    int x,y;
    read();
    pregen();
    din();
    for(int i=1;i<=q;i++)
    {
        f>>x>>y;
        x=rmq(x,y);
        printf("%d\n",x);
    }
    return 0;
}