Cod sursa(job #1755693)

Utilizator Luncasu_VictorVictor Luncasu Luncasu_Victor Data 10 septembrie 2016 19:46:22
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.98 kb
#include <algorithm>
#include <string>
#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <map>
#include <queue>
using namespace std;

#ifdef INFOARENA
#define TEST 0
#else
#define TEST 1
#endif

class IntervalTree {
 public:
  IntervalTree(const vector<int> &values) {
    num_values_ = values.size();
    for (int i = 0; i < values.size(); ++i) {
      // Construct segments
      UpdateInternal(0, 0, num_values_ - 1, i, values[i]);
    }
  }
  int QueryMax(int left_pos, int right_pos) {
    int answer = 0;
    QueryMaxInternal(0, left_pos, right_pos, 0, num_values_ - 1, answer);
    return answer;
  }
  void QueryMaxInternal(int node, int left_pos, int right_pos, int left_segment_pos, int right_segment_pos, int &answer) {
    if (left_pos <= left_segment_pos && right_segment_pos <= right_pos) {
      // This segment fits into searched positions
      answer = max(answer, segments_[node]);
      return;
    }
    int middle_segment_pos = (left_segment_pos + right_segment_pos) / 2;
    if (left_pos <= middle_segment_pos) {
      // Need to collect data from the overlapping part
      QueryMaxInternal(2 * node + 1, left_pos, right_pos, left_segment_pos, middle_segment_pos, answer);
    }
    if (right_pos > middle_segment_pos) {
      QueryMaxInternal(2 * node + 2, left_pos, right_pos, middle_segment_pos + 1, right_segment_pos, answer);
    }
  }
  void Update(int pos_to_update, int value) {
    UpdateInternal(0, 0, num_values_ - 1, pos_to_update, value);
  }
  void UpdateInternal(int node, int left_pos, int right_pos, int pos_to_update, int value) {
    if (left_pos == right_pos) {
      // Single element segment
      if (node >= segments_.size()) {
        // Assure also that the right subsegment will fit.
        segments_.resize(2 * node + 2);
      }
      segments_[node] = value;
      return;
    }
    int middle_pos = (left_pos + right_pos) / 2;
    if (pos_to_update <= middle_pos) {
      UpdateInternal(2 * node + 1, left_pos, middle_pos, pos_to_update, value);
    } else {
      UpdateInternal(2 * node + 2, middle_pos + 1, right_pos, pos_to_update, value);
    }
    // Update maximum on this interval
    segments_[node] = max(segments_[2 * node + 1], segments_[2 * node + 2]);
  }


 private:
  vector<int> segments_;
  int num_values_;
};

int main() {
  freopen("arbint.in","r",stdin);
  freopen("arbint.out","w", stdout);
  int num_values, num_queries;
  scanf("%d %d", &num_values, &num_queries);
  vector<int> values;
  values.resize(num_values);
  for (int i = 0; i < num_values; ++i) {
    scanf("%d", &values[i]);
  }
  IntervalTree *instance = new IntervalTree(values);
  int type, left_pos, right_pos;
  for (int i = 0; i < num_queries; ++i) {
    scanf("%d %d %d", &type, &left_pos, &right_pos);
    if (type == 0) {
      printf("%d\n", instance->QueryMax(left_pos - 1, right_pos - 1));
    } else {
      int pos_to_update = left_pos;
      int value_for_update = right_pos;
      instance->Update(pos_to_update - 1, value_for_update);
    }
  }

  return 0;
}