Problem p02352 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <iostream>
#include <math.h>
#include <queue>
#include <set>
#include <vector>
using namespace std;
const int INF = 2000000000;
typedef unsigned long long ull;
typedef long long ll;

class SegmentTree {
  vector<pair<int, int>> st;
  int realSize;

  void buildTree_() {
    for (int i = (((int)st.size() + 1) >> 1) - 2; i >= 0; i--) {
      st[i].first = std::max(st[(i << 1) + 1].first, st[(i << 1) + 2].first);
    }
  }

  void push_(int index) {
    if (st[index].second == 0)
      return;
    st[index].first += st[index].second;
    st[(index << 1) + 1].second += st[index].second;
    st[(index << 1) + 2].second += st[index].second;
    st[index].second = 0;
  }

  int max_(int index, int leftBorder, int rightBorder, int left, int right) {
    if (leftBorder > right || rightBorder < left)
      return INF;
    if (leftBorder >= left && rightBorder <= right)
      return st[index].first + st[index].second;
    push_(index);
    int middle = (leftBorder + rightBorder) >> 1;
    return std::min(
        max_((index << 1) + 1, leftBorder, middle, left, right),
        max_((index << 1) + 2, middle + 1, rightBorder, left, right));
  }

  void add_(int index, int leftBorder, int rightBorder, int left, int right,
            int difference) {
    if (leftBorder > right || rightBorder < left)
      return;
    if (leftBorder >= left && rightBorder <= right) {
      st[index].second += difference;
      return;
    }
    push_(index);
    int middle = (leftBorder + rightBorder) >> 1;
    add_((index << 1) + 1, leftBorder, middle, left, right, difference);
    add_((index << 1) + 2, middle + 1, rightBorder, left, right, difference);
    st[index].first = std::min(
        max_((index << 1) + 1, leftBorder, middle, leftBorder, rightBorder),
        max_((index << 1) + 2, middle + 1, rightBorder, leftBorder,
             rightBorder));
  }

public:
  SegmentTree(int size) : realSize(size) {
    st.resize((ull)(1 << ((int)floor(log(size) / log(2.0)) + 2)) - 1);
  }

  friend istream &operator>>(istream &in, SegmentTree &stree) {
    int lowStart = (int)stree.st.size() >> 1;
    for (int i = 0; i < stree.realSize; i++) {
      int x;
      in >> x;
      stree.st[lowStart + i].first = x;
      stree.st[lowStart + i].second = 0;
    }
    stree.buildTree_();
    return in;
  }

  friend ostream &operator<<(ostream &out, SegmentTree &stree) {
    set<int> s = {0, 2, 6, 14};
    out << "Tree: (size = " << stree.st.size() << ")\\n";
    for (int i = 0; i < (int)stree.st.size(); i++) {
      out << "(" << stree.st[i].first << ", " << stree.st[i].second << ") ";
      if (s.find(i) != s.end())
        out << '\\n';
    }
    return out;
  }

  int max(int left, int right) {
    return max_(0, 0, (int)st.size() >> 1, left, right);
  }

  void add(int left, int right, int difference) {
    add_(0, 0, (int)st.size() >> 1, left, right, difference);
  }

  SegmentTree() = default;
  SegmentTree(const SegmentTree &) = delete;
  SegmentTree &operator=(const SegmentTree &) = delete;
};

// Класс обработчика запросов.
class Solution {
  struct Query {
    int from, to, ticketsNumber;
    Query(int from_, int to_, int ticketsNumber_)
        : from(from_), to(to_ - 1), ticketsNumber(ticketsNumber_) {}
  };

  vector<Query> queries;
  vector<int> answer;
  int n, capacity, m;

public:
  Solution(int n_, int capacity_, int m_) : n(n_), capacity(capacity_), m(m_) {}

  void solve(SegmentTree &st) {
    for (int i = 0; i < m; i++) {
      if (st.max(queries[i].from, queries[i].to) + queries[i].ticketsNumber >
          capacity)
        answer.push_back(i);
      else
        st.add(queries[i].from, queries[i].to, queries[i].ticketsNumber);
    }
  }

  friend istream &operator>>(istream &in, Solution &s) {
    for (int i = 0; i < s.m; i++) {
      int from, to, ticketsNumber;
      in >> from >> to >> ticketsNumber;
      s.queries.push_back(Query(from, to, ticketsNumber));
    }
    return in;
  }

  friend ostream &operator<<(ostream &out, Solution &s) {
    for (auto x : s.answer)
      out << x << " ";
    return out;
  }

  Solution() = default;
  Solution(const Solution &) = delete;
  Solution &operator=(const Solution &) = delete;
};

void solve() {
  /*int n, capacity, m;
  cin >> n;
  SegmentTree st(n - 1);
  cin >> st >> capacity >> m;
  cout << st;
  Solution solution(n - 1, capacity, m);
  cin >> solution;
  solution.solve(st);
  cout << solution;*/
  int n, m;
  cin >> n;
  SegmentTree st(n);
  cin >> m;
  for (int i = 0; i < m; i++) {
    int c;
    cin >> c;
    if (c == 1) {
      int l, r;
      cin >> l >> r;
      // cout << "Query: " << c << " " << l << " " << r << '\\n';
      cout << st.max(l, r) << '\\n';
    }
    if (c == 0) {
      int l, r, d;
      cin >> l >> r >> d;
      // cout << "Query: " << c << " " << l << " " << r << " " << d << '\\n';
      st.add(l, r, d);
    }
    // cout << st;
  }
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  solve();
  return 0;
}


Error: WA

Fixed submission:

/* Длинное условие*/
// T(n, m) = O((n + m) * log(n))
// M(n, m) = O(n + m)

#include <algorithm>
#include <iostream>
#include <math.h>
#include <queue>
#include <set>
#include <vector>
using namespace std;
const int INF = 2000000000;
typedef unsigned long long ull;
typedef long long ll;

class SegmentTree {
  vector<pair<int, int>> st;
  int realSize;

  void buildTree_() {
    for (int i = (((int)st.size() + 1) >> 1) - 2; i >= 0; i--) {
      st[i].first = std::max(st[(i << 1) + 1].first, st[(i << 1) + 2].first);
    }
  }

  void push_(int index) {
    if (st[index].second == 0 || (index << 1) + 1 >= (int)st.size())
      return;
    st[index].first += st[index].second;
    st[(index << 1) + 1].second += st[index].second;
    st[(index << 1) + 2].second += st[index].second;
    st[index].second = 0;
  }

  int max_(int index, int leftBorder, int rightBorder, int left, int right) {
    if (leftBorder > right || rightBorder < left)
      // return 0;
      return INF;
    if (leftBorder >= left && rightBorder <= right)
      return st[index].first + st[index].second;
    push_(index);
    int middle = (leftBorder + rightBorder) >> 1;
    // надо std::max
    return std::min(
        max_((index << 1) + 1, leftBorder, middle, left, right),
        max_((index << 1) + 2, middle + 1, rightBorder, left, right));
  }

  int add_(int index, int leftBorder, int rightBorder, int left, int right,
           int difference) {
    if (leftBorder > right || rightBorder < left)
      return st[index].first + st[index].second;
    if (leftBorder >= left && rightBorder <= right) {
      st[index].second += difference;
      return st[index].first + st[index].second;
    }
    push_(index);
    int middle = (leftBorder + rightBorder) >> 1;
    // надо std::max
    st[index].first = std::min(
        add_((index << 1) + 1, leftBorder, middle, left, right, difference),
        add_((index << 1) + 2, middle + 1, rightBorder, left, right,
             difference));
  }

public:
  SegmentTree(int size) : realSize(size) {
    st.resize((ull)(1 << ((int)floor(log(size) / log(2.0)) + 2)) - 1);
  }

  friend istream &operator>>(istream &in, SegmentTree &stree) {
    int lowStart = (int)stree.st.size() >> 1;
    for (int i = 0; i < stree.realSize; i++) {
      int x;
      in >> x;
      stree.st[lowStart + i].first = x;
      stree.st[lowStart + i].second = 0;
    }
    stree.buildTree_();
    return in;
  }

  friend ostream &operator<<(ostream &out, SegmentTree &stree) {
    set<int> s = {0, 2, 6, 14};
    out << "Tree: (size = " << stree.st.size() << ")\\n";
    for (int i = 0; i < (int)stree.st.size(); i++) {
      out << "(" << stree.st[i].first << ", " << stree.st[i].second << ") ";
      if (s.find(i) != s.end())
        out << '\\n';
    }
    return out;
  }

  int max(int left, int right) {
    return max_(0, 0, (int)st.size() >> 1, left, right);
  }

  void add(int left, int right, int difference) {
    int c = add_(0, 0, (int)st.size() >> 1, left, right, difference);
  }

  SegmentTree() = default;
  SegmentTree(const SegmentTree &) = delete;
  SegmentTree &operator=(const SegmentTree &) = delete;
};

// Класс обработчика запросов.
class Solution {
  struct Query {
    int from, to, ticketsNumber;
    Query(int from_, int to_, int ticketsNumber_)
        : from(from_), to(to_ - 1), ticketsNumber(ticketsNumber_) {}
  };

  vector<Query> queries;
  vector<int> answer;
  int n, capacity, m;

public:
  Solution(int n_, int capacity_, int m_) : n(n_), capacity(capacity_), m(m_) {}

  void solve(SegmentTree &st) {
    // cout << "capacity: " << capacity << '\\n';
    for (int i = 0; i < m; i++) {
      // cout << "Query: " << queries[i].from << " " << queries[i].to << " " <<
      // queries[i].ticketsNumber << '\\n'; cout << "max: " <<
      // st.max(queries[i].from, queries[i].to) << '\\n';
      if (st.max(queries[i].from, queries[i].to) + queries[i].ticketsNumber >
          capacity)
        answer.push_back(i);
      else
        st.add(queries[i].from, queries[i].to, queries[i].ticketsNumber);
      // cout << '\\n' << st;
    }
  }

  friend istream &operator>>(istream &in, Solution &s) {
    for (int i = 0; i < s.m; i++) {
      int from, to, ticketsNumber;
      in >> from >> to >> ticketsNumber;
      s.queries.push_back(Query(from, to, ticketsNumber));
    }
    return in;
  }

  friend ostream &operator<<(ostream &out, Solution &s) {
    for (auto x : s.answer)
      out << x << " ";
    return out;
  }

  Solution() = default;
  Solution(const Solution &) = delete;
  Solution &operator=(const Solution &) = delete;
};

void solve() {
  /*int n, capacity, m;
  cin >> n;
  SegmentTree st(n - 1);
  cin >> st >> capacity >> m;
  cout << st;
  Solution solution(n - 1, capacity, m);
  cin >> solution;
  solution.solve(st);
  cout << solution;*/
  int n, m;
  cin >> n;
  SegmentTree st(n);
  cin >> m;
  int cnt = 0;
  for (int i = 0; i < m; i++) {
    int c;
    cin >> c;
    if (c == 1) {
      int l, r;
      cin >> l >> r;
      if (cnt)
        cout << '\\n';
      // cout << "Query: " << c << " " << l << " " << r << '\\n';
      cout << st.max(l, r);
      cnt++;
    }
    if (c == 0) {
      int l, r, d;
      cin >> l >> r >> d;
      // cout << "Query: " << c << " " << l << " " << r << " " << d << '\\n';
      st.add(l, r, d);
    }
    // cout << st;
  }
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  solve();
  return 0;
}