Cod sursa(job #1672531)

Utilizator stoianmihailStoian Mihail stoianmihail Data 2 aprilie 2016 20:30:54
Problema Range minimum query Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.37 kb
#include <stdio.h>

#define Nadejde 100001

int N, M;
int tree[Nadejde << 1];

/** min(X, Y). **/
int MIN(int X, int Y) {
  return X < Y ? X : Y;
}

/** Aduna-l pe "val" cu "N". **/
void inc(int *val) {
  (*val) += N;
}

/** Construieste arborele de intervale. **/
void build() {
  int i;

  for (i = N - 1; i > 0; i--) {
    tree[i] = MIN(tree[i << 1], tree[(i << 1) | 1]);
  }
}

/** Pozitia "pos" va primi valoarea "val". **/
void update(int pos, int val) {
  inc(&pos);
  tree[pos] = val;
  while (pos > 1) {
    tree[pos >> 1] = MIN(tree[pos], tree[pos ^ 1]);
    pos >>= 1;
  }
}

/** Gaseste maximul din intervalul "b" -> "e". **/
int query(int b, int e) {
  int u = Nadejde, v = Nadejde;

  inc(&b);
  inc(&e);
  while (b < e) {
    if (b & 1) {
      u = MIN(u, tree[b++]);
    }
    if (e & 1) {
      v = MIN(v, tree[--e]);
    }
    b >>= 1, e >>= 1;
  }
  return MIN(u, v);
}

int main(void) {
  int i, b, e;
  FILE *f = fopen("rmq.in", "r");

  /* Citirea datelor. */
  fscanf(f, "%d %d", &N, &M);
  for (i = 0; i < N; i++) {
    fscanf(f, "%d", &tree[i + N]);
  }

  /* Construirea arborelui de intervale. */
  build();

  /* Raspunde la intrebari. */
  freopen("rmq.out", "w", stdout);
  while (M) {
    fscanf(f, "%d %d", &b, &e);
    fprintf(stdout, "%d\n", query(b - 1, e));
    M--;
  }
  fclose(f);
  fclose(stdout);

  /// Multumim Doamne!
  puts("Doamne ajuta!");
  return 0;
}