Cod sursa(job #2975444)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 6 februarie 2023 15:47:35
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.43 kb
#include <cstdio>
#include <memory>
#include <vector>
#include <algorithm>

using namespace std;


class SegmentTree{
private:
  vector<int> elem;
  int arrSize;
  
  void Build(typename vector<int>::iterator begin, typename vector<int>::iterator end, int pz) {
    if (distance(begin, end) == 1) {
      elem[pz] = *begin;
      return;
    }
    int middleDist = distance(begin, end) / 2;
    Build(begin, begin + middleDist, pz * 2 + 1);
    Build(begin + middleDist, end, pz * 2 + 2);
    elem[pz] = max(elem[pz * 2 + 1], elem[pz * 2 + 2]);
  }

  void Update(int begin, int end, int pz, int updatePos, int newValue) {
    if (end - begin == 1) {
      elem[pz] = newValue;
      return;
    }
    int middleDist = (end - begin) / 2;
    if (begin + middleDist > updatePos)
      Update(begin, begin + middleDist, pz * 2 + 1, updatePos, newValue);
    else
      Update(begin + middleDist, end, pz * 2 + 2, updatePos, newValue);
    elem[pz] = max(elem[pz * 2 + 1], elem[pz * 2 + 2]);
  }

  int QueryMax(int begin, int end, int pz, int left, int right) {
    if (left <= begin && end <= right + 1) {
      return elem[pz];
    }
    int middleDist = (end - begin) / 2;
    int maxLeft = -1, maxRight = -1;

    if (begin + middleDist > left)
      maxLeft = QueryMax(begin, begin + middleDist, pz * 2 + 1, left, right);
    if (right >= begin + middleDist)
      maxRight = QueryMax(begin + middleDist, end, pz * 2 + 2, left, right);

    return max(maxLeft, maxRight);
  }
public:
  SegmentTree(vector<int> arr) {
    if (arr.empty())
      return;
    arrSize = (int)arr.size();
    elem.resize(arrSize* 4);
    Build(arr.begin(), arr.end(), 0);
  }
  void Update(int updatePos, int newValue) {
    Update(0, arrSize, 0, updatePos, newValue);
  }
  int QueryMax(int left, int right) {
    return QueryMax(0, arrSize, 0, left, right);
  }
};

class Solver{
public:
  Solver() {
    freopen("arbint.in", "r", stdin);
    freopen("arbint.out", "w", stdout);
  }
  ~Solver() {
    fclose(stdin);
    fclose(stdout);
  }
  void solve() {
    int N, M;
    scanf("%d%d", &N, &M);
    vector<int> v(N);
    for (int i = 0; i < N; ++i)
      scanf("%d", &v[i]);

    SegmentTree tree(v);
    
    int a, b, op;
    for (int i = 0; i < M; ++i) {
      scanf("%d%d%d", &op, &a, &b);
      if (op == 1) 
	tree.Update(a - 1, b);
      else 
	printf("%d\n", tree.QueryMax(a - 1, b - 1));
    }
  }
};


int main() {
  unique_ptr<Solver> s = make_unique<Solver>();
  s->solve();
  return 0;
}