Cod sursa(job #3132312)

Utilizator daryusoctavyanDarius Octavian Chifor daryusoctavyan Data 22 mai 2023 03:06:35
Problema Arbori de intervale Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.43 kb
#include <bits/stdc++.h>
#include <fstream>

using namespace std;

using i64 = int64_t;

template <typename T> class segment_tree {
private:
  vector<T> __values;
  size_t __size;
  size_t __capacity;
  function<T(T, T)> __func;

  size_t get_capacity(size_t n) {
    size_t res = 1;
    while (res < n) {
      res *= 2;
    }

    return res;
  }

  T __query(size_t pos, size_t left, size_t right, size_t left_bound,
            size_t right_bound) {
    if (left == left_bound and right == right_bound) {
      return __values[pos];
    }

    size_t mid = left_bound + (right_bound - left_bound) / 2;

    if (right <= mid) {
      return __query(pos * 2, left, right, left_bound, mid);
    }
    if (left > mid) {
      return __query(pos * 2 + 1, left, right, mid + 1, right_bound);
    }
    return __func(__query(pos * 2, left, mid, left_bound, mid),
                  __query(pos * 2 + 1, mid + 1, right, mid + 1, right_bound));
  }

public:
  segment_tree(size_t to_allocate, T fill, function<T(T, T)> fn) {
    this->__size = to_allocate;
    this->__capacity = get_capacity(to_allocate);
    this->__values.assign(__capacity << 1, fill);
    this->__func = fn;
  }

  size_t size() { return __size; }
  size_t capacity() { return __capacity; }
  T get(size_t pos) { return __values[__capacity + pos]; }

  void assign(size_t pos, T element) {
    if (pos > __size) {
      throw std::invalid_argument("index out of bounds");
    }

    pos = __capacity + pos;
    __values[pos] = element;
    pos /= 2;

    while (pos != 0) {
      __values[pos] = __func(__values[pos * 2], __values[pos * 2 + 1]);
      pos /= 2;
    }
  }

  T query(size_t left, size_t right) {
    if (right >= __size or left >= __size or left < 0 or right < 0) {
      throw std::invalid_argument("query out of range");
    }

    if (left > right) {
      throw std::invalid_argument("invalid query");
    }

    return __query(1, left, right, 0, __capacity - 1);
  }

  void print() {
    for (auto &e : __values) {
      cout << e << " ";
    }
    cout << endl;
  }
};

int main() {
  ifstream cin{"arbint.in"};
  ofstream cout{"arbint.out"};

  i64 n, m;
  cin >> n >> m;

  segment_tree<i64> s(n, 0, [](i64 a, i64 b) { return max(a, b); });
  for (i64 i = 0; i < n; i++) {
    i64 x;
    cin >> x;
    s.assign(i, x);
  }

  while (m--) {
    i64 op, a, b;
    cin >> op >> a >> b;

    if (op == 0) {
      cout << s.query(a - 1, b - 1);
    } else {
      s.assign(a - 1, b);
    }
  }

  return 0;
}