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

#include <vector>
template <typename T> class LazyPropagationSegmentTree {
public:
  LazyPropagationSegmentTree(int n) : size_(1) {
    while (size_ < n)
      size_ <<= 1;
    node_.assign(size_ << 1, 0);
    lazy_.assign(size_ << 1, 0);
  }
  T find(int left, int right) { return find(left, right + 1, 1, 0, size_); }
  void add(int left, int right, T value) {
    add(left, right + 1, value, 1, 0, size_);
  }

private:
  int left_child(int node) const { return node << 1; }
  int right_child(int node) const { return (node << 1) + 1; }
  T find(int a, int b, int k, int l, int r) {
    if (b <= l || r <= a)
      return 0;
    if (a <= l && r <= b)
      return node_.at(k) + (r - l) * lazy_.at(k);
    lazy_.at(left_child(k)) += lazy_.at(k);
    lazy_.at(right_child(k)) += lazy_.at(k);
    lazy_.at(k) = 0;
    auto vl = find(a, b, left_child(k), l, (l + r) / 2);
    auto vr = find(a, b, right_child(k), (l + r) / 2, r);
    return vl + vr;
  }
  T add(int a, int b, T value, int k, int l, int r) {
    if (b <= l || r <= a)
      return node_.at(k) + (r - l) * lazy_.at(k);
    if (a <= l && r <= b)
      return node_.at(k) + (r - l) * (lazy_.at(k) += value);
    lazy_.at(left_child(k)) += lazy_.at(k);
    lazy_.at(right_child(k)) += lazy_.at(k);
    lazy_.at(k) = 0;
    auto vl = add(a, b, value, left_child(k), l, (l + r) / 2);
    auto vr = add(a, b, value, right_child(k), (l + r) / 2, r);
    return node_.at(k) = vl + vr;
  }
  int size_;
  std::vector<T> node_;
  std::vector<T> lazy_;
};

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

struct Node {
  int f;
  long long h;
};
bool operator<(const Node &lhs, const Node &rhs) {
  if (lhs.h != rhs.h)
    return lhs.h < rhs.h;
  return lhs.f < rhs.f;
}

int main() {
  int N, H;
  cin >> N >> H;

  LazyPropagationSegmentTree<long long> hp(N + 1);
  hp.add(0, N, H);

  long long answer = 0;
  int last = 0;
  priority_queue<Node> q;

  for (int i = 1; i < N; ++i) {
    long long d, h;
    cin >> d >> h;

    q.push({i, h});
    hp.add(i, N, -d);

    while (hp.find(i, i) <= 0) {
      auto node = q.top();

      if (node.f < last) {
        q.pop();
        continue;
      }

      if (H < node.h + hp.find(node.f - 1, node.f - 1)) {
        q.pop();
        q.push({node.f, H - hp.find(node.f - 1, node.f - 1)});
        continue;
      }

      last = node.f;
      int use = min((-hp.find(i, i) / node.h) + 1,
                    (H - hp.find(node.f - 1, node.f - 1)) / node.h);
      answer += use;
      hp.add(node.f - 1, N, use * node.h);
    }
  }

  cout << answer << endl;
}

Error: TLE

Fixed submission:

#include <vector>
template <typename T> class LazyPropagationSegmentTree {
public:
  LazyPropagationSegmentTree(int n) : size_(1) {
    while (size_ < n)
      size_ <<= 1;
    node_.assign(size_ << 1, 0);
    lazy_.assign(size_ << 1, 0);
  }
  T find(int left, int right) { return find(left, right + 1, 1, 0, size_); }
  void add(int left, int right, T value) {
    add(left, right + 1, value, 1, 0, size_);
  }

private:
  int left_child(int node) const { return node << 1; }
  int right_child(int node) const { return (node << 1) + 1; }
  T find(int a, int b, int k, int l, int r) {
    if (b <= l || r <= a)
      return 0;
    if (a <= l && r <= b)
      return node_.at(k) + (r - l) * lazy_.at(k);
    lazy_.at(left_child(k)) += lazy_.at(k);
    lazy_.at(right_child(k)) += lazy_.at(k);
    lazy_.at(k) = 0;
    auto vl = find(a, b, left_child(k), l, (l + r) / 2);
    auto vr = find(a, b, right_child(k), (l + r) / 2, r);
    return vl + vr;
  }
  T add(int a, int b, T value, int k, int l, int r) {
    if (b <= l || r <= a)
      return node_.at(k) + (r - l) * lazy_.at(k);
    if (a <= l && r <= b)
      return node_.at(k) + (r - l) * (lazy_.at(k) += value);
    lazy_.at(left_child(k)) += lazy_.at(k);
    lazy_.at(right_child(k)) += lazy_.at(k);
    lazy_.at(k) = 0;
    auto vl = add(a, b, value, left_child(k), l, (l + r) / 2);
    auto vr = add(a, b, value, right_child(k), (l + r) / 2, r);
    return node_.at(k) = vl + vr;
  }
  int size_;
  std::vector<T> node_;
  std::vector<T> lazy_;
};

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

struct Node {
  int f;
  long long h;
};
bool operator<(const Node &lhs, const Node &rhs) {
  if (lhs.h != rhs.h)
    return lhs.h < rhs.h;
  return lhs.f < rhs.f;
}

int main() {
  int N, H;
  cin >> N >> H;

  LazyPropagationSegmentTree<long long> hp(N + 1);
  hp.add(0, N, H);

  long long answer = 0;
  int last = 0;
  priority_queue<Node> q;

  for (int i = 1; i < N; ++i) {
    long long d, h;
    cin >> d >> h;

    q.push({i, h});
    hp.add(i, N, -d);

    while (hp.find(i, i) <= 0) {
      auto node = q.top();

      if (node.f < last) {
        q.pop();
        continue;
      }

      if (node.h + hp.find(node.f - 1, node.f - 1) <= H) {
        last = node.f;
        ++answer;
        hp.add(node.f - 1, N, node.h);
        continue;
      }

      q.pop();
      q.push({node.f, H - hp.find(node.f - 1, node.f - 1)});
    }
  }

  cout << answer << endl;
}