Cod sursa(job #157141)

Utilizator nimicLeoveanu Mihaita Alexandru nimic Data 12 martie 2008 21:26:39
Problema Range minimum query Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <cstdio>
#include <algorithm>
#define MaxN 101000
#define BUCKET 512
#define Dim (1<<13)
#define bucket(x) ((x)/BUCKET)
#define first(x) ((x)*BUCKET)

using namespace std;

unsigned n, m, poz;
unsigned val[MaxN], minBuc[MaxN/BUCKET];
char lin[Dim];

inline void cit(unsigned &x){
	x=0;
	while (lin[poz]<'0' || lin[poz]>'9'){
          poz++;
	      if (poz == Dim) fread(lin, 1, Dim, stdin), poz=0;   
    }
	while (lin[poz]>='0' && lin[poz]<='9'){
		x = 10*x+lin[poz++]-'0';     
        if (poz == Dim) fread(lin, 1, Dim, stdin), poz=0; 
	}            
}

inline void scrie(unsigned k){
     char lin[12], *s;
     s=lin+29; s[0]=0;
     do {
        unsigned cat=k/10;
        s--;
        s[0]=k-cat*10+'0';
        k=cat;
     } while (k);
     puts(s);
}

inline void query(unsigned st, unsigned fn){
	unsigned b1 = bucket(st), b2 = bucket(fn);
	unsigned sol = MaxN;
	for (unsigned i=b1+1; i<b2; i++)
		if (minBuc[i] < sol) sol = minBuc[i];
	if (sol > minBuc[b1])
		for (unsigned i=st; i<first(b1+1) && i<=fn; i++)
			if (val[i] < sol) sol = val[i];
	if (sol > minBuc[b2])
		for (unsigned i=max(first(b2), st); i<=fn; i++)
			if (val[i] < sol) sol = val[i];
	scrie(sol);
}

int main(){
	freopen("rmq.in", "r", stdin);
	freopen("rmq.out", "w", stdout);
	cit(n); cit(m);
	memset(minBuc, 0x7f, sizeof(minBuc));
	for (unsigned i=0; i<n; i++){
		cit(val[i]);
		if (val[i] < minBuc[bucket(i)]) minBuc[bucket(i)] = val[i];
	}
	while (m--){
		unsigned a, b;
		cit(a); cit(b);
		query(a-1, b-1);
	}
}