Cod sursa(job #3150583)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 17 septembrie 2023 16:01:43
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.64 kb
#include <fstream>
#include <functional>
#include <vector>

template <typename T> class Merger {
private:
  std::function<T(const T &, const T &)> f;

public:
  Merger(std::function<T(const T &, const T &)> _f) : f{_f} {};
  T operator()(const T &a, const T &b) { return f(a, b); }
};

template <typename T> class SegmentTree {
private:
  int n;
  std::vector<T> nodes;
  Merger<T> f;

  void build(int node, int l, int r, const std::vector<T> &v);

  void update(int node, int l, int r, int pos, const T &v);

  T query(int node, int l, int r, int ql, int qr);

public:
  SegmentTree(const std::vector<T> &v, const Merger<T> &f);

  void Update(int pos, const T &v);

  T Query(int l, int r);
};

template <typename T>
void SegmentTree<T>::build(int node, int l, int r, const std::vector<T> &v) {
  if (l == r) {
    nodes[node] = v[l - 1];
    return;
  }

  int mid = (l + r) >> 1;
  build(node << 1, l, mid, v);
  build(node << 1 | 1, mid + 1, r, v);

  nodes[node] = f(nodes[node << 1], nodes[node << 1 | 1]);
}

template <typename T>
void SegmentTree<T>::update(int node, int l, int r, int pos, const T &v) {
  if (l == r) {
    nodes[node] = v;
    return;
  }

  int mid = (l + r) >> 1;
  if (pos <= mid)
    update(node << 1, l, mid, pos, v);
  else
    update(node << 1 | 1, mid + 1, r, pos, v);

  nodes[node] = f(nodes[node << 1], nodes[node << 1 | 1]);
}

template <typename T>
T SegmentTree<T>::query(int node, int l, int r, int ql, int qr) {
  if (ql <= l && r <= qr)
    return nodes[node];

  int mid = (l + r) >> 1;
  if (qr <= mid)
    return query(node << 1, l, mid, ql, qr);
  if (ql > mid)
    return query(node << 1 | 1, mid + 1, r, ql, qr);

  T a = query(node << 1, l, mid, ql, mid),
    b = query(node << 1 | 1, mid + 1, r, mid + 1, qr);
  return f(a, b);
}

template <typename T>
SegmentTree<T>::SegmentTree(const std::vector<T> &v, const Merger<T> &_f)
    : f{_f} {
  n = (int)v.size();
  nodes.resize(4 * n);

  build(1, 1, n, v);
}

template <typename T> void SegmentTree<T>::Update(int pos, const T &v) {
  update(1, 1, n, pos, v);
}

template <typename T> T SegmentTree<T>::Query(int l, int r) {
  return query(1, 1, n, l, r);
}

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

  int n, m;
  cin >> n >> m;
  std::vector<int> v(n);
  for (int i = 0; i < n; i++)
    cin >> v[i];

  SegmentTree<int> seg_tree(v, Merger<int>{[](const int &a, const int &b) {
                              return std::max(a, b);
                            }});

  for (int i = 0; i < m; i++) {
    int t, a, b;
    cin >> t >> a >> b;
    if (t == 0)
      cout << seg_tree.Query(a, b) << '\n';
    else
      seg_tree.Update(a, b);
  }

  return 0;
}