Cod sursa(job #1526629)

Utilizator danny794Dan Danaila danny794 Data 16 noiembrie 2015 22:26:41
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <cstdio>
#include <cmath>

#define NMAX (1 << 18)

using namespace std;

int N, M, elts;
int v[NMAX];

inline int max(int a, int b) {
  return a > b ? a : b;
}

void read() {
  freopen("arbint.in", "r", stdin);
  freopen("arbint.out", "w", stdout);
  scanf("%d %d\n", &N, &M);
  elts = (int) (log(N) / log(2));
  if ((1 << elts) < N) {
    elts += 1;
  }
  elts = 1 << elts;
  for (int i = 0; i < N; i++) {
    scanf("%d", &v[elts + i]);
  }
  int first = elts;
  while (first > 1) {
    first >>= 1;
    for (int j = first; j < 2 * first; j++) {
      v[j] = max(v[2 * j], v[2 * j + 1]);
    }
  }
}

int getMax(int level, int pos, int a, int b) {
  int left  = 1 + pos * (elts >> level);
  int right = (pos + 1) * (elts >> level);
  int index = (1 << level) + pos;
  if (a == left && b == right) {
    return v[index];
  }

  int middle = (left + right) >> 1;
  if (b <= middle) {
    return getMax(level + 1, 2 * pos, a, b);
  } else if (a > middle) {
    return getMax(level + 1, 2 * pos + 1, a, b);
  } else {
    return max(getMax(level + 1, 2 * pos, a, middle),
               getMax(level + 1, 2 * pos + 1, middle + 1, b));
  }
}

void update(int pos, int val) {
  pos = elts + pos - 1;
  v[pos] = val;
  while (pos > 1) {
    pos >>= 1;
    v[pos] = max(v[(pos << 1)], v[(pos << 1) + 1]);
  }
}

void solve() {
  int a, b, type;
  for (int i = 0; i < M; i++) {
    scanf("%d %d %d", &type, &a, &b);
    if (type == 0) {
      printf("%d\n", getMax(0, 0, a, b));
    } else {
      update(a, b);
    }
  }
}

int main() {
  read();
  solve();
  return 0;
}