Problem p02758 (C++)

Buggy submission (status: Time Limit Exceeded):
// -----------------------------------
// Author     : MatsuTaku
// Affiliation: Tokushima University
// Country    : Japan
// Date       : 07/03/2020
// -----------------------------------

#include <bits/stdc++.h>

using namespace std;
using ll = long long;

template <typename T> class max_segment_tree {
  size_t mpt_;
  vector<T> vec_;

public:
  max_segment_tree(size_t size) {
    mpt_ = 1;
    while (mpt_ < size)
      mpt_ <<= 1;
    vec_.resize(mpt_ + size, 0);
  }
  void update(size_t index, long long value) {
    auto i = mpt_ + index;
    vec_[i] = value;
    i /= 2;
    while (i > 0) {
      vec_[i] = max(vec_[i * 2], vec_[i * 2 + 1]);
      cerr << "up " << i << "] " << vec_[i] << endl;
      i /= 2;
    }
  }
  long long operator[](size_t i) const { return vec_[mpt_ + i]; }
  long long range_max(size_t l, size_t r, size_t _l = 0,
                      size_t _r = numeric_limits<size_t>::max(),
                      size_t _d = 1) const {
    if (_r == numeric_limits<size_t>::max())
      _r = mpt_;
    if (_r <= l or r <= _l) {
      return 0;
    } else if (l <= _l and _r <= r) {
      return vec_[_d];
    } else {
      return max(range_max(l, r, _l, (_l + _r) / 2, _d * 2),
                 range_max(l, r, (_l + _r) / 2, _r, _d * 2 + 1));
    }
  }
};

constexpr long long MOD = 998244353;

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);

  int N;
  cin >> N;
  vector<pair<int, int>> R(N);
  for (int i = 0; i < N; i++) {
    cin >> R[i].first >> R[i].second;
  }
  sort(R.begin(), R.end());

  vector<long long> dp(N + 1);
  dp.back() = 1;
  max_segment_tree<long long> sg(N);
  for (int i = N - 1; i >= 0; i--) {
    int l = i, r = N;
    while (l + 1 < r) {
      auto c = (l + r) / 2;
      if (R[c].first < R[i].first + R[i].second) {
        l = c;
      } else {
        r = c;
      }
    }

    sg.update(i, i);
    auto edge = sg.range_max(i, r);
    sg.update(i, edge);
    dp[i] = dp[i + 1] + dp[edge + 1];
    dp[i] %= MOD;
  }
  cout << dp[0] << endl;

  return 0;
}


Fixed submission:
// -----------------------------------
// Author     : MatsuTaku
// Affiliation: Tokushima University
// Country    : Japan
// Date       : 07/03/2020
// -----------------------------------

#include <bits/stdc++.h>

using namespace std;
using ll = long long;

template <typename T> class max_segment_tree {
  size_t mpt_;
  vector<T> vec_;

public:
  max_segment_tree(size_t size) {
    mpt_ = 1;
    while (mpt_ < size)
      mpt_ <<= 1;
    vec_.resize(mpt_ + size, 0);
  }
  void update(size_t index, long long value) {
    auto i = mpt_ + index;
    vec_[i] = value;
    i /= 2;
    while (i > 0) {
      vec_[i] = max(vec_[i * 2], vec_[i * 2 + 1]);
      i /= 2;
    }
  }
  long long operator[](size_t i) const { return vec_[mpt_ + i]; }
  long long range_max(size_t l, size_t r, size_t _l = 0,
                      size_t _r = numeric_limits<size_t>::max(),
                      size_t _d = 1) const {
    if (_r == numeric_limits<size_t>::max())
      _r = mpt_;
    if (_r <= l or r <= _l) {
      return 0;
    } else if (l <= _l and _r <= r) {
      return vec_[_d];
    } else {
      return max(range_max(l, r, _l, (_l + _r) / 2, _d * 2),
                 range_max(l, r, (_l + _r) / 2, _r, _d * 2 + 1));
    }
  }
};

constexpr long long MOD = 998244353;

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);

  int N;
  cin >> N;
  vector<pair<int, int>> R(N);
  for (int i = 0; i < N; i++) {
    cin >> R[i].first >> R[i].second;
  }
  sort(R.begin(), R.end());

  vector<long long> dp(N + 1);
  dp.back() = 1;
  max_segment_tree<long long> sg(N);
  for (int i = N - 1; i >= 0; i--) {
    int l = i, r = N;
    while (l + 1 < r) {
      auto c = (l + r) / 2;
      if (R[c].first < R[i].first + R[i].second) {
        l = c;
      } else {
        r = c;
      }
    }

    sg.update(i, i);
    auto edge = sg.range_max(i, r);
    sg.update(i, edge);
    dp[i] = dp[i + 1] + dp[edge + 1];
    dp[i] %= MOD;
  }
  cout << dp[0] << endl;

  return 0;
}