Cod sursa(job #2524803)

Utilizator greenadexIulia Harasim greenadex Data 16 ianuarie 2020 12:37:22
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.4 kb
#include <fstream>
#include <string>
#include <vector>
#include <iostream>

const std::string kInputFileName = "arbint.in";
const std::string kOutputFileName = "arbint.out";

class IntervalTree {
public:
  explicit IntervalTree(int num_elems) : num_elems_(num_elems), tree_(num_elems * 4, 0) {}

  int GetMax(int start, int end) {
    return GetMax(0, num_elems_ - 1, start, end, 0);
  }

  void ModifyElem(int position, int new_value) {
    ModifyElem(0, num_elems_ - 1, 0, position, new_value);
  }

private:
  void ModifyElem(int left, int right, int node, int position, int new_value) {
    if (left == right) {
      tree_[node] = new_value;
      return;
    }

    int mid = (left + right) / 2;
    int left_child_node = node * 2 + 1;
    int right_child_node = left_child_node + 1;
    if (position <= mid) {
      ModifyElem(left, mid, left_child_node, position, new_value);
    } else {
      ModifyElem(mid + 1, right, right_child_node, position, new_value);
    }

    tree_[node] = std::max(tree_[left_child_node], tree_[right_child_node]);
  }

  int GetMax(int current_start, int current_end, int start, int end, int node) {
    if (current_start > current_end) {
      return 0;
    }

    if (start <= current_start && current_end <= end) {
      return tree_[node];
    }

    int mid = (current_start + current_end) / 2;

    int max_left = 0;
    if (start <= mid) {
      max_left = GetMax(current_start, mid, start, end, node * 2 + 1);
    }

    int max_right = 0;
    if (end > mid) {
      max_right = GetMax(mid + 1, current_end, start, end, node * 2 + 2);
    }
    return std::max(max_left, max_right);
  }

  const int num_elems_;
  std::vector<int> tree_;
};

int main() {
  std::ifstream fin(kInputFileName);
  std::ofstream fout(kOutputFileName);

  int num_elems;
  fin >> num_elems;

  IntervalTree tree(num_elems);

  int num_ops;
  fin >> num_ops;

  for (int i = 0; i < num_elems; i++) {
    int elem;
    fin >> elem;
    tree.ModifyElem(i, elem);
  }

  for (int i = 0; i < num_ops; i++) {
    int op_type;
    fin >> op_type;
    switch (op_type) {
      case 0:
        int left;
        int right;
        fin >> left >> right;
        fout << tree.GetMax(left - 1, right - 1) << '\n';
        break;
      case 1:
        int position;
        int new_val;
        fin >> position >> new_val;
        tree.ModifyElem(position - 1, new_val);
        break;
      default:
        return -1;
    }
  }

  return 0;
}