Cod sursa(job #3291876)

Utilizator catalintermureTermure Catalin catalintermure Data 5 aprilie 2025 22:34:38
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.8 kb
#include <fstream>
#include <functional>
#include <iostream>

using namespace std;

ifstream inf("arbint.in");
ofstream outf("arbint.out");

template <typename T, T neutral_val, typename BinaryOperation>
struct IntervalTree {
  struct Node {
    T value;
    int left, right;
  };

  std::vector<Node> tree;
  BinaryOperation op;

  IntervalTree(BinaryOperation op, const std::vector<T>& data) : op(op) {
    int n = data.size();
    tree.resize(4 * n);
    build(0, 0, n - 1, data);
  }

  void build(int node, int start, int end, const std::vector<T>& data) {
    if (start == end) {
      tree[node].value = data[start];
      tree[node].left = tree[node].right = start;
    } else {
      int mid = (start + end) / 2;
      build(2 * node + 1, start, mid, data);
      build(2 * node + 2, mid + 1, end, data);
      tree[node].value = op(tree[2 * node + 1].value, tree[2 * node + 2].value);
      tree[node].left = start;
      tree[node].right = end;
    }
  }

  T query(int node, int start, int end) {
    if (start > tree[node].right || end < tree[node].left) {
      return neutral_val;
    }
    if (start <= tree[node].left && end >= tree[node].right) {
      return tree[node].value;
    }
    return op(query(2 * node + 1, start, end), query(2 * node + 2, start, end));
  }

  T query(int start, int end) { return query(0, start, end); }

  void print(int node = 0) {
    cout << "Node " << node << ": [" << tree[node].left << ", " << tree[node].right << "] = " << tree[node].value
         << "\n";
    if (tree[node].left != tree[node].right) {
      print(2 * node + 1);
      print(2 * node + 2);
    }
  }

  void update(int node, int index, T value) {
    if (tree[node].left == tree[node].right) {
      tree[node].value = value;
    } else {
      int mid = (tree[node].left + tree[node].right) / 2;
      if (index <= mid) {
        update(2 * node + 1, index, value);
      } else {
        update(2 * node + 2, index, value);
      }
      tree[node].value = op(tree[2 * node + 1].value, tree[2 * node + 2].value);
    }
  }

  void update(int index, T value) { update(0, index, value); }

  void print_tree() {
    for (int i = 0; i < tree.size(); ++i) {
      cout << "Node " << i << ": [" << tree[i].left << ", " << tree[i].right << "] = " << tree[i].value << "\n";
    }
  }
};

int main() {
  int n, m;
  inf >> n >> m;
  std::vector<int> data(n);
  for (int i = 0; i < n; ++i) {
    inf >> data[i];
  }

  auto op = [](int a, int b) { return std::max(a, b); };
  IntervalTree<int, 0, decltype(op)> tree(op, data);

  for (int i = 0; i < m; ++i) {
    int type, x, y;
    inf >> type >> x >> y;
    if (type == 1) {
      tree.update(x - 1, y);
    } else {
      outf << tree.query(x - 1, y - 1) << "\n";
    }
  }

  return 0;
}