Cod sursa(job #2157985)

Utilizator andreigasparoviciAndrei Gasparovici andreigasparovici Data 10 martie 2018 08:27:34
Problema Arbori de intervale Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.24 kb
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <functional>
using namespace std;
 
const int NMAX = 100005;
const int SQRTMAX = 360;

const function<int(int,int)> OPERATIE = [](int x, int y) { return (x > y) ? x : y;  };
const int ELEMENT_NEUTRU  = -1;

struct {
  int inc, sf;
}b[SQRTMAX];

int n, m, _sqrt, nb, a[NMAX], value[SQRTMAX];
 
#define which(i) (ceil(1.0 * i / _sqrt))

void init() {
  _sqrt = sqrt(n);
  nb = which(n);
 
  b[1].inc = 1;
  b[1].sf = _sqrt;
 
  for (int i = 2; i <= nb; i++) {
    b[i].inc = b[i - 1].sf + 1;
    b[i].sf = b[i].inc + _sqrt - 1;
    value[i] = ELEMENT_NEUTRU;
  }
 
  b[nb].sf = min(b[nb].sf, n);
}
 
void citire() {
  for (int i = 1; i <= n; i++) {
    scanf("%d ", &a[i]);
    const int k = which(i);
    value[k] = OPERATIE(value[k], a[i]);
  }
}
 
int runQuery(int st, int dr) {
  const int bSt = which(st), bDr = which(dr);
  int query = ELEMENT_NEUTRU;
 
  if (bSt == bDr) {
    if (st == b[bSt].inc && dr == b[bDr].sf) {
      return value[bSt];
    } else {
      for (int i = st; i <= dr; i++) {
        query = OPERATIE(query, a[i]);
      }
      return query;
    }
  }
 
  if (st > b[bSt].inc) {
    for (int i = st; i <= b[bSt].sf; i++) {
      query = OPERATIE(query, a[i]);
    }
  } else if (st == b[bSt].inc) {
    query = OPERATIE(query, value[bSt]);
  }
 
  for (int i = bSt + 1; i < bDr; i++) {
    query = OPERATIE(query, value[i]);
  }

  if (dr < b[bDr].sf) {
    for (int i = b[bDr].inc; i <= dr; i++) {
      query = OPERATIE(query, a[i]);
    }
  } else if (dr == b[bDr].sf) {
    query = OPERATIE(query, value[bDr]);
  }
 
  return query;
}
 
void runUpdate(int pos, int val) {
  a[pos] = val;
  const int k = which(pos);

  if (val > value[k]) {
    value[k] = val;
  } else {
    value[k] = ELEMENT_NEUTRU;
    for (int i = b[k].inc; i <= b[k].sf; i++) {
      value[k] = OPERATIE(value[k], a[i]);
    }
  }
}
 
void rezolvare() {
  for (int i = 1; i <= m; i++) {
    int tip, a, b;
    scanf("%d %d %d ", &tip, &a, &b);
 
    if (tip == 1) {
      runUpdate(a, b);
    } else {
      printf("%d\n", runQuery(a, b));
    }
  }
 
}
 
int main() {
  freopen("arbint.in", "r", stdin);
  freopen("arbint.out", "w", stdout);
 
  scanf("%d %d ", &n, &m);
 
  init();
  citire();
  rezolvare();

  return 0;
}