Cod sursa(job #156113)

Utilizator marcelcodreaCodrea Marcel marcelcodrea Data 12 martie 2008 12:52:07
Problema Range minimum query Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.79 kb
// Se da un vector si doi indici
// Sa se determine pozitia elementului minim situat intre cei doi indici.
// Rezolvare cu arbore de intervale

#include <fstream>
#include <iostream>

using namespace std;

fstream fi("rmq.in",ios::in);
fstream fo("rmq.out",ios::out);
int n, i, a[100001], m[1000000], s, d;

void initai (int nod, int b, int e, int n) { // initializarea arborelui de intervale
  if (b == e) // begin, end
    m[nod] = b;
  else {
    initai (2*nod,           b, (b+e)/2, n);
    initai (2*nod+1, (b+e)/2+1,       e, n);
    if (a[m[2*nod]] <= a[m[2*nod+1]]) // Comparam minimele din subarborii fiilor.
      m[nod] = m[2*nod];
    else
      m[nod] = m[2*nod+1];
  }
}
int cerere (int nod, int b, int e, int s, int d) {
  int mins, mind;

  if (d < b || e < s)   // Intervalul curent si cel de cautare nu se intersecteaza
    return -1;
  if (s <= b && e <= d) // Intervalul curent este in interiorul intervalului de cautare
    return m[nod];
  else {
    mins = cerere (2*nod,           b, (b+e)/2, s, d); // minimul din stanga
    mind = cerere (2*nod+1, (b+e)/2+1,       e, s, d); // minimul din dreapta
    if (mins == -1)
      return mind;
    if (mind == -1)
      return mins;
    if (a[mins] <= a[mind])
      return mins;
    else
      return mind;
  }
}
int main() {
	fi >> n >> m;
	for (i = 1; i <= n; i++) {
		fi >> a[i];
	}
	cout << endl;
	initai (1, 1, n, n);
	for (i = 1; i <= m; i++)
	{
			fi>>s>>d;
			fout<<a[cerere(1, 1, n, s, d)]<<endl;
	}
  cout << endl;
  return 0;
}

/*
Cazurile posibile in cerere:
( ) [   ]       caz 1
s d b   e

 (  [ ) ]       caz 3
 s  b d e

 (  [   ] )     caz 2
 s  b   e d

    [ ()]       caz 3
    b sde

    [ ( ] )     caz 3
    b s e d

    [   ] ()    caz 1
    b   e sd
*/