Problem p02788 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;

#define time_assert(x)                                                         \
  if (!(x))                                                                    \
    while (true)

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(NULL);
  int n, d, a;
  cin >> n >> d >> a;
  vector<pair<int, int>> monsters;
  for (int i = 0; i < n; i++) {
    int x, h;
    cin >> x >> h;
    h = (h + a - 1) / a;
    monsters.emplace_back(x, h);
  }
  sort(monsters.begin(), monsters.end());
  time_assert((int)monsters.size() == n);

  int base = 1;
  while (base < n) {
    base *= 2;
  }
  vector<long long> tree(2 * base);
  for (int i = 0; i < n; i++) {
    tree[base + i] = monsters[i].second;
  }
  auto get_health = [&](int i) {
    int total = 0;
    for (int j = base + i; j >= 1; j /= 2) {
      total += tree[j];
    }
    return total;
  };
  auto add_interval = [&](int L, int R, int x) {
    L += base;
    R += base;
    tree[L] += x;
    if (L != R) {
      tree[R] += x;
    }
    while (L + 1 < R) {
      if (L % 2 == 0) {
        tree[L + 1] += x;
      }
      if (R % 2 == 1) {
        tree[R - 1] += x;
      }
      L /= 2;
      R /= 2;
    }
  };

  long long answer = 0;
  for (int i = 0; i < n; i++) {
    int my_health = get_health(i);
    if (my_health <= 0) { // already killed
      continue;
    }
    // find the last monster still hit by a bomb starting here
    int low = i, high = n - 1;
    int ok = -1;
    while (low <= high) {
      int mid = (low + high) / 2;
      if (monsters[mid].first <= monsters[i].first + 2 * d) {
        ok = mid;
        low = mid + 1;
      } else {
        high = mid - 1;
      }
    }
    time_assert(ok != -1);
    add_interval(i, ok, -my_health);
    answer += my_health;
  }
  cout << answer << endl;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

#define time_assert(x)                                                         \
  if (!(x))                                                                    \
    while (true)

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(NULL);
  int n, d, a;
  cin >> n >> d >> a;
  vector<pair<int, int>> monsters;
  for (int i = 0; i < n; i++) {
    int x, h;
    cin >> x >> h;
    h = (h + a - 1) / a;
    monsters.emplace_back(x, h);
  }
  sort(monsters.begin(), monsters.end());
  time_assert((int)monsters.size() == n);

  int base = 1;
  while (base < n) {
    base *= 2;
  }
  vector<long long> tree(2 * base);
  for (int i = 0; i < n; i++) {
    tree[base + i] = monsters[i].second;
  }
  auto get_health = [&](int i) {
    int total = 0;
    for (int j = base + i; j >= 1; j /= 2) {
      total += tree[j];
    }
    return total;
  };
  auto add_interval = [&](int L, int R, int x) {
    L += base;
    R += base;
    tree[L] += x;
    if (L != R) {
      tree[R] += x;
    }
    while (L + 1 < R) {
      if (L % 2 == 0) {
        tree[L + 1] += x;
      }
      if (R % 2 == 1) {
        tree[R - 1] += x;
      }
      L /= 2;
      R /= 2;
    }
  };

  long long answer = 0;
  for (int i = 0; i < n; i++) {
    int my_health = get_health(i);
    if (my_health <= 0) { // already killed
      continue;
    }
    // find the last monster still hit by a bomb starting here
    int low = i, high = n - 1;
    int ok = -1;
    while (low <= high) {
      int mid = (low + high) / 2;
      if (monsters[mid].first <= monsters[i].first + 2LL * d) {
        ok = mid;
        low = mid + 1;
      } else {
        high = mid - 1;
      }
    }
    time_assert(ok != -1);
    add_interval(i, ok, -my_health);
    answer += my_health;
  }
  cout << answer << endl;
}