Cod sursa(job #1051991)

Utilizator classiusCobuz Andrei classius Data 10 decembrie 2013 19:42:15
Problema Range minimum query Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.92 kb
// 8.12.2013
// Range Minimum Query
// <O(N)> Pre-processing time
// <O(logN)> Query time
// Method: Segment Tree

using namespace std;

#include<fstream>
#include<cmath>
#include<algorithm>

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

const int MAXN=100000;
int A[MAXN],M[MAXN*4];

void initialize(int nod,int lf,int rt){
    if(rt==lf){ //leaf node
        //because a leaf represent a single element from array A,
        //it will contain that element
        M[nod]=rt;
        return;
    }

    initialize(nod*2,lf,(lf+rt)/2); //initialize M for the left part of the interval [lf,rt]
    initialize(nod*2+1,(lf+rt)/2+1,rt);

    //Now that we have computed the index of the minimum element in the
    //Interval [lf,(lf+rt)/2] and in the interval [(lf+rt)/2+1,rt], we can
    //Use it to find the index of the minimum element from the interval [lf,rt]
    if(A[M[nod*2]]>A[M[nod*2+1]])
        M[nod]=M[nod*2+1];
    else M[nod]=M[nod*2];
    return;
}

int query(int nod,int lf,int rt,int x,int y){
    // the current interval doesn't intersect the queried interval
    if(y<lf || x>rt)
        return -1;

    // the current interval is included in the queried interval
    if(lf>=x && rt<=y)
        return M[nod];

    int p1,p2;

    // the index of the minimum element in interval [lf,rt] by using the
    // its' two halves
    p1=query(nod*2,lf,(lf+rt)/2,x,y);
    p2=query(nod*2+1,(lf+rt)/2+1,rt,x,y);

    if(p1==-1) return p2; // the first half is not included in the queried interval
    if(p2==-1) return p1; // the second half is not include in the queried interval
    if(A[p1]<A[p2]) return p1;
    return p2;
}

int main(){
    int N;

    cin>>N;
    int Q;
    cin>>Q;
    for(int i=0;i<N;i++)
        cin>>A[i];

    initialize(1,0,N-1); // I build the segment tree using the A array

    
    while(Q--){
        int x,y;
        cin>>x>>y;
	x--; y--;
        cout<<A[query(1,0,N-1,x,y)]<<'\n';
    }

    return 0;
}