Problem p02750 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
using namespace std;

typedef pair<int, int> pii;

const int N = 35;

pii a[200010];
long long dp[200010][40];
long long sum[200010];

bool cmp(pii a, pii b) {
  return (long double)a.fi / (a.se + 1) > (long double)b.fi / (b.se + 1);
}

int main() {
  int n, T;
  scanf("%d%d", &n, &T);
  for (int i = 0; i < n; i++) {
    scanf("%d%d", &a[i].fi, &a[i].se);
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < n; k++) {
        if (i == j || j == k || i == k)
          continue;
        if (cmp(a[i], a[j]) && cmp(a[j], a[k]) && !cmp(a[i], a[k]))
          assert(0);
        if (!cmp(a[i], a[j]) && !cmp(a[j], a[k]) && cmp(a[i], a[k]))
          assert(0);
      }
    }
  }
  sort(a, a + n, cmp);
  int mid = 0;
  while (mid < n && a[mid].fi != 0)
    mid++;
  sort(a + mid, a + n);
  for (int i = mid; i < n; i++) {
    sum[i] = a[i].se + 1;
    if (i != mid)
      sum[i] += sum[i - 1];
  }
  for (int i = 0; i <= N; i++) {
    dp[0][i] = 0x3f3f3f3f;
  }
  dp[0][0] = 0;
  int ans = 0;
  for (int i = 0; i < mid; i++) {
    for (int j = N; j >= 1; j--) {
      long long tmp = dp[i][j - 1];
      tmp++, tmp += tmp * a[i].fi + a[i].se;
      tmp = min(tmp, (long long)T + 1);
      dp[i + 1][j] = min(dp[i][j], tmp);
      int pos = upper_bound(sum + mid, sum + n, T - dp[i][j]) - sum;
      if (dp[i][j] <= T)
        ans = max(ans, j + pos - mid);
    }
  }
  for (int j = 0; j <= N; j++) {
    long long minj = 0x3f3f3f3f;
    for (int i = 0; i <= mid; i++) {
      minj = min(minj, dp[i][j]);
    }
    int pos = upper_bound(sum + mid, sum + n, T - minj) - sum;
    if (minj <= T)
      ans = max(ans, j + pos - mid);
  }
  printf("%d\n", ans);
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
using namespace std;

typedef pair<int, int> pii;

const int N = 35;

pii a[200010];
long long dp[200010][40];
long long sum[200010];

bool cmp(pii a, pii b) {
  return (long double)a.fi / (a.se + 1) > (long double)b.fi / (b.se + 1);
}

int main() {
  int n, T;
  scanf("%d%d", &n, &T);
  for (int i = 0; i < n; i++) {
    scanf("%d%d", &a[i].fi, &a[i].se);
  }
  sort(a, a + n, cmp);
  int mid = 0;
  while (mid < n && a[mid].fi != 0)
    mid++;
  sort(a + mid, a + n);
  for (int i = mid; i < n; i++) {
    sum[i] = a[i].se + 1;
    if (i != mid)
      sum[i] += sum[i - 1];
  }
  for (int i = 0; i <= N; i++) {
    dp[0][i] = 0x3f3f3f3f;
  }
  dp[0][0] = 0;
  int ans = 0;
  for (int i = 0; i < mid; i++) {
    for (int j = N; j >= 1; j--) {
      long long tmp = dp[i][j - 1];
      tmp++, tmp += tmp * a[i].fi + a[i].se;
      tmp = min(tmp, (long long)T + 1);
      dp[i + 1][j] = min(dp[i][j], tmp);
      int pos = upper_bound(sum + mid, sum + n, T - dp[i][j]) - sum;
      if (dp[i][j] <= T)
        ans = max(ans, j + pos - mid);
    }
  }
  for (int j = 0; j <= N; j++) {
    long long minj = 0x3f3f3f3f;
    for (int i = 0; i <= mid; i++) {
      minj = min(minj, dp[i][j]);
    }
    int pos = upper_bound(sum + mid, sum + n, T - minj) - sum;
    if (minj <= T)
      ans = max(ans, j + pos - mid);
  }
  printf("%d\n", ans);
  return 0;
}