Cod sursa(job #3250616)

Utilizator JohnnyFortaPascu Ioan JohnnyForta Data 22 octombrie 2024 13:17:54
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.96 kb
#include <vector>
#include <fstream>
#include <iostream>

class SegmentTree{
  struct Node{
    int value;
    Node operator+(const Node & node){
      return Node{std::max(node.value, value)};
    }
    friend std::ostream& operator<<(std::ostream& os, const Node& n){
      os<<n.value;
    }
  };
  std::vector<Node> v;
  int noNodes;

  void build(int currentNode, int left, int right, std::vector<int>& list){
    if(left == right){
      v[currentNode].value = list[left];
      return;
    }

    int mid = (left + right) / 2,
    leftChild = currentNode + 1,
    rightChild = currentNode + 2 * (mid - left + 1);
    build(leftChild, left, mid, list);
    build(rightChild, mid + 1, right, list);
    v[currentNode] = v[leftChild] + v[rightChild];
  }

  void innerReplace(int index, int value, int currentNode, int left, int right){
    if(left == right){
      v[currentNode].value = value;
      return;
    }

    int mid = (left + right) / 2,
    leftChild = currentNode + 1,
    rightChild = currentNode + 2 * (mid - left + 1);
    if(index <= mid)
      innerReplace(index, value, leftChild, left, mid);
    else
      innerReplace(index, value, rightChild, mid + 1, right);
    v[currentNode] = v[leftChild] + v[rightChild];
  }

  Node innerQuery(int currentNode, int left, int right, int queryLeft, int queryRight){
    if(left == queryLeft && right == queryRight){
      return v[currentNode];
    }

    int mid = (left + right) / 2,
    leftChild = currentNode + 1,
    rightChild = currentNode + 2 * (mid - left + 1);
    if(queryRight <= mid)
      return innerQuery(leftChild, left, mid, queryLeft, queryRight);
    if(mid < queryLeft)
      return innerQuery(rightChild, mid + 1, right, queryLeft, queryRight);
    return innerQuery(leftChild, left, mid, queryLeft, mid) +
      innerQuery(rightChild, mid + 1, right, mid + 1, queryRight);
  }

  public:
  SegmentTree(std::vector<int>& list){
    noNodes = list.size();
    v.resize(2 * noNodes - 1);
    build(0, 0, noNodes - 1, list);
  }

  void replace(int index, int value){
    innerReplace(index, value, 0, 0, noNodes - 1);
  }

  int query(int left, int right){
    if(left < 0 || right >= noNodes){
      std::cout<<"Out of bounds query\n";
      return 0;
    }
    if(left > right){
      std::cout<<"Invalid query\n";
      return 0;
    }
    Node a = innerQuery(0, 0, noNodes - 1, left, right);
    return a.value;
  }

  void show(){
    for(auto node : v){
      std::cout<<node<<' ';
    }
    std::cout<<std::endl;
  }
};


int main(){
  int n, m, op, op1, op2;
  std::ifstream in("arbint.in");
  std::ofstream out("arbint.out");
  std::vector<int> x;
  in>>n>>m;
  x.resize(n);
  for(int i = 0; i < n; i++){
    in>>x[i];
  }
  SegmentTree v(x);
  for(int i = 0; i < m; i++){
    in>>op>>op1>>op2;
    if(op == 0){
      out<<v.query(op1 - 1, op2 - 1)<<std::endl;
    }else{
      v.replace(op1 - 1, op2);
    }
  }
}