Problem p00476 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef pair<ll, ll> P;

#define rep(i, n) for (ll(i) = 0; (i) < (n); ++i)

#define rep1(i, n) for (ll(i) = 1; (i) <= (n); ++i)

#define rrep(i, n) for (ll(i) = (n)-1; (i) >= (0); --i)

#define rrep1(i, n) for (ll(i) = (n); (i) >= (1); --i)

#define pb push_back

#define fr first

#define sc second

const ll INF = 0xfffffffffffff;
const ll inf = 0xfffffff;
const ll SIZE = 1 << 17;
priority_queue<P> q;
ll N, HP;
ll D[100000], H[100000];
ll hp[SIZE];

ll ans = 0;
ll l = 0;
ll pos;
ll data[SIZE * 2 - 1], datb[SIZE * 2 - 1];
ll init(ll k) {
  datb[k] = 0;
  if (k >= SIZE - 1)
    return data[k] = hp[k - SIZE + 1];
  return data[k] = max(init(k * 2 + 1), init(k * 2 + 2));
}

ll update(ll a, ll b, ll val, ll k, ll l, ll r) {
  if (a > b)
    swap(a, b);
  if (b <= l || r <= a)
    return data[k] + datb[k];
  if (a <= l && r <= b) {
    datb[k] += val;
    return data[k] + datb[k];
  } else {
    data[k] = max(update(a, b, val, k * 2 + 1, l, (l + r) / 2),
                  update(a, b, val, k * 2 + 2, (l + r) / 2, r));
    return data[k] + datb[k];
  }
}

ll query(ll a, ll b, ll k, ll l, ll r) {
  if (r <= a || b <= l)
    return -INF;
  if (a <= l && r <= b)
    return data[k] + datb[k];
  else
    return max(query(a, b, k * 2 + 1, l, (l + r) / 2),
               query(a, b, k * 2 + 2, (l + r) / 2, r)) +
           datb[k];
}

int main()

{
  ll ans = 0;

  cin >> N >> HP;
  hp[0] = HP;
  rep(i, N - 1) {
    cin >> D[i] >> H[i];
    hp[i + 1] = hp[i] - D[i];
  }
  init(0);
  pos = HP;
  ll want;
  ll z, zan;
  rep(i, N - 1) {
    q.push(P(H[i], i));
    while (pos - D[i] < 1) {
      want = D[i] - pos + 1;
      P p = q.top();
      q.pop();
      zan = HP - query(p.sc, i + 1, 0, 0, SIZE);
      if (zan < p.fr) {
        q.push(P(zan, p.sc));
      } else if ((zan / p.fr) * p.fr <= want) {
        z = zan / p.fr;
        ans += z;
        pos += z * p.fr;
        update(p.sc, N, z * p.fr, 0, 0, SIZE);
        if (zan % p.fr != 0) {
          q.push(P(zan % p.fr, p.sc));
        }
      } else {
        z = (want - 1) / p.fr + 1;
        ans += z;
        pos += z * p.fr;
        update(p.sc, N, z * p.fr, 0, 0, SIZE);
        q.push(p);
      }
    }
    pos -= D[i];
  }
  cout << ans << endl;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

// typedef pair<ll,ll> P;

#define rep(i, n) for (ll(i) = 0; (i) < (n); ++i)

#define rep1(i, n) for (ll(i) = 1; (i) <= (n); ++i)

#define rrep(i, n) for (ll(i) = (n)-1; (i) >= (0); --i)

#define rrep1(i, n) for (ll(i) = (n); (i) >= (1); --i)

#define pb push_back

#define fr first

#define sc second

const ll INF = 0xfffffffffffff;
const ll inf = 0xfffffff;
const ll SIZE = 1 << 17;
struct P {
  ll h, id, j;
  bool operator<(const P &an) const {
    if (h != an.h)
      return h < an.h;
    if (id != an.id)
      return id > an.id;
    return j < an.j;
  }
  bool operator>(const P &an) const {
    if (h != an.h)
      return h > an.h;
    if (id != an.id)
      return id < an.id;
    return j > an.j;
  }
};
ll N, HP;
ll pos;
ll H[SIZE], D[SIZE];
P dat[SIZE * 2 - 1];
ll lazy[SIZE * 2 - 1];

P init(ll k) {
  lazy[k] = 0;
  if (SIZE - 1 <= k) {
    return dat[k] = P{H[k - SIZE + 1], k - SIZE + 1, HP};
  }
  return dat[k] = max(init(k * 2 + 1), init(k * 2 + 2));
}

void lazy_ev(ll k) {
  if (lazy[k] == 0)
    return;
  dat[k].j += lazy[k];
  if (k >= SIZE - 1) {
    dat[k].h = min(dat[k].h, dat[k].j);
  } else {
    dat[k].h = min(dat[k].h, dat[k].j);
    lazy[k * 2 + 1] = lazy[k * 2 + 2] = lazy[k];
  }
  lazy[k] = 0;
  return;
}

P query(ll a, ll b, ll k, ll l, ll r) { //???????????§?????¨index
  lazy_ev(k);
  if (r <= a || b <= l)
    return P{-INF, -1, -INF};
  if (a <= l && r <= b)
    return dat[k];
  return max(query(a, b, k * 2 + 1, l, (l + r) / 2),
             query(a, b, k * 2 + 2, (l + r) / 2, r));
}

P update(ll a, ll b, ll val, ll k, ll l, ll r) {
  lazy_ev(k);
  if (b <= l || r <= a)
    return dat[k];
  if (a <= l && r <= b) {
    lazy[k] = val;
    lazy_ev(k);
  } else {
    dat[k] = max(update(a, b, val, k * 2 + 1, l, (l + r) / 2),
                 update(a, b, val, k * 2 + 2, (l + r) / 2, r));
  }
  return dat[k];
}

ll ans = 0;
ll l = 0;

int main()

{

  cin >> N >> HP;
  rep(i, SIZE) H[i] = -INF;
  rep(i, N - 1) { cin >> D[i] >> H[i]; }
  init(0);
  pos = HP;
  ll z;
  rep(i, N - 1) {
    update(i, i + 1, -pos, 0, 0, SIZE);
    while (pos - D[i] <= 0) {
      P p = query(l, i + 1, 0, 0, SIZE);
      if (p.h == p.j) {
        pos += p.h;
        ans++;
        update(p.id, i + 1, -p.h, 0, 0, SIZE);
      } else {
        z = p.j / p.h;
        pos += p.h * z;
        ans += z;
        update(p.id, i + 1, -p.h * z, 0, 0, SIZE);
      }
      l = p.id;
    }
    pos -= D[i];
  }
  cout << ans << endl;
}