Problem p02788 (C++)

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

#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define endl '\n'
#define fcin                                                                   \
  ios::sync_with_stdio(false);                                                 \
  cin.tie(nullptr);
#define inf 0x3f3f3f3f
#define all(x) x.begin(), x.end()
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

typedef long long ll;
typedef pair<int, int> pii;

/*
 * * stuff you should look for
 * * int overflow, array bounds
 * * special cases (n=1?), set tle
 * */

int n, d, a;
vector<pii> mon;

struct SegTree {
  vector<ll> st, lazy;

  SegTree() {
    st.resize(4 * n + 4, 0);
    lazy.resize(4 * n + 4, 0);
  }

  void build(int p, int l, int r) {
    if (l == r)
      st[p] = mon[l - 1].se;
    else {
      int mid = (l + r) / 2;
      build(p + p, l, mid);
      build(p + p + 1, mid + 1, r);
      st[p] = st[p + p] + st[p + p + 1];
    }
  }

  void prop(int p, int l, int r) {
    if (lazy[p]) {
      st[p] += lazy[p] * (r - l + 1);
      if (l != r) {
        lazy[p + p] += lazy[p];
        lazy[p + p + 1] += lazy[p];
      }
      lazy[p] = 0;
    }
  }

  void upd(int p, int l, int r, int a, int b, ll x) {
    prop(p, l, r);
    if (l > b or r < a)
      return;
    if (l >= a and r <= b) {
      lazy[p] += x;
      prop(p, l, r);
    } else {
      int mid = (l + r) / 2;
      upd(p + p, l, mid, a, b, x);
      upd(p + p + 1, mid + 1, r, a, b, x);
      st[p] = st[p + p] + st[p + p + 1];
    }
  }

  ll query(int p, int l, int r, int a, int b) {
    prop(p, l, r);
    if (l > b or r < a)
      return 0;
    if (l >= a and r <= b)
      return st[p];
    else {
      int mid = (l + r) / 2;
      ll x = query(p + p, l, mid, a, b);
      ll y = query(p + p + 1, mid + 1, r, a, b);
      return x + y;
    }
  }
};

int main() {
  fcin;

  cin >> n >> d >> a;

  for (int i = 0; i < n; i++) {
    int x, h;
    cin >> x >> h;

    h = (h + a - 1) / a;

    mon.eb(x, h);
  }

  sort(all(mon));

  SegTree s;
  s.build(1, 1, n);

  ll ans = 0;
  for (int i = 0; i < n; i++) {
    ll hp = s.query(1, 1, n, i + 1, i + 1);
    if (hp <= 0)
      continue;

    int x = mon[i].fi;
    int lo = i, hi = n - 1;

    int last = -1;
    while (lo <= hi) {
      int mid = (lo + hi) / 2;

      if (x + 2 * d >= mon[mid].fi) {
        last = mid;
        lo = mid + 1;
      } else
        hi = mid - 1;
    }

    assert(last != -1);

    ans += hp;
    s.upd(1, 1, n, i + 1, last + 1, -hp);
  }

  cout << ans << endl;
  return 0;
}


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

#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define endl '\n'
#define fcin                                                                   \
  ios::sync_with_stdio(false);                                                 \
  cin.tie(nullptr);
#define inf 0x3f3f3f3f
#define all(x) x.begin(), x.end()
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

typedef long long ll;
typedef pair<int, int> pii;

/*
 * * stuff you should look for
 * * int overflow, array bounds
 * * special cases (n=1?), set tle
 * */

int n, d, a;
vector<pii> mon;

struct SegTree {
  vector<ll> st, lazy;

  SegTree() {
    st.resize(4 * n + 4, 0);
    lazy.resize(4 * n + 4, 0);
  }

  void build(int p, int l, int r) {
    if (l == r)
      st[p] = mon[l - 1].se;
    else {
      int mid = (l + r) / 2;
      build(p + p, l, mid);
      build(p + p + 1, mid + 1, r);
      st[p] = st[p + p] + st[p + p + 1];
    }
  }

  void prop(int p, int l, int r) {
    if (lazy[p]) {
      st[p] += lazy[p] * (r - l + 1);
      if (l != r) {
        lazy[p + p] += lazy[p];
        lazy[p + p + 1] += lazy[p];
      }
      lazy[p] = 0;
    }
  }

  void upd(int p, int l, int r, int a, int b, ll x) {
    prop(p, l, r);
    if (l > b or r < a)
      return;
    if (l >= a and r <= b) {
      lazy[p] += x;
      prop(p, l, r);
    } else {
      int mid = (l + r) / 2;
      upd(p + p, l, mid, a, b, x);
      upd(p + p + 1, mid + 1, r, a, b, x);
      st[p] = st[p + p] + st[p + p + 1];
    }
  }

  ll query(int p, int l, int r, int a, int b) {
    prop(p, l, r);
    if (l > b or r < a)
      return 0;
    if (l >= a and r <= b)
      return st[p];
    else {
      int mid = (l + r) / 2;
      ll x = query(p + p, l, mid, a, b);
      ll y = query(p + p + 1, mid + 1, r, a, b);
      return x + y;
    }
  }
};

int main() {
  fcin;

  cin >> n >> d >> a;

  for (int i = 0; i < n; i++) {
    int x, h;
    cin >> x >> h;

    h = (h + a - 1) / a;

    mon.eb(x, h);
  }

  sort(all(mon));

  SegTree s;
  s.build(1, 1, n);

  ll ans = 0;
  for (int i = 0; i < n; i++) {
    ll hp = s.query(1, 1, n, i + 1, i + 1);
    if (hp <= 0)
      continue;

    int x = mon[i].fi;
    int lo = i, hi = n - 1;

    int last = -1;
    while (lo <= hi) {
      int mid = (lo + hi) / 2;

      if (x + (ll)2 * d >= mon[mid].fi) {
        last = mid;
        lo = mid + 1;
      } else
        hi = mid - 1;
    }

    assert(last != -1);

    ans += hp;
    s.upd(1, 1, n, i + 1, last + 1, -hp);
  }

  cout << ans << endl;
  return 0;
}