Cod sursa(job #1250423)

Utilizator juniorOvidiu Rosca junior Data 28 octombrie 2014 09:19:47
Problema Range minimum query Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.74 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>

using namespace std;

ifstream fi("rmq.in");
ofstream fo("rmq.out");
int n, q, i, a[100001], m[300003], s, d;

void initai (int nod, int b, int e) { // initializarea arborelui de intervale
  if (b == e) // begin, end
    m[nod] = b;
  else {
    initai (2 * nod,                   b, (b + e) / 2);
    initai (2 * nod + 1, (b + e) / 2 + 1,           e);
    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 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); // minimul din stanga
    mind = cerere (2 * nod + 1, (b + e) / 2 + 1,       e); // 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 >> q;
  for (i = 1; i <= n; i++)
    fi >> a[i];
  initai (1, 1, n);
  for (i = 1; i <= q; i++) {
    fi >> s >> d;
    fo << a[cerere(1, 1, n)] << '\n';
  }
  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
*/