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

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define LL long long
#define FOR(i, s, t) for (int i = (int)s; i < (int)t; ++i)
using namespace std;
const int maxn = 100010;

int n, li[maxn];
LL L, sum[maxn], c[maxn];

struct Num {
  LL a, b;
  bool operator<(const Num &rhs) const { return a - b > rhs.a - rhs.b; }
} s[maxn];

void Init() {
  LL ca = 0;
  int idx = 1;
  FOR(i, 2, n + 1) {
    ca = ca + s[i].a - s[i].b - c[idx];
    if (ca <= 0)
      break;
    ++idx;
  }
  li[1] = idx;
  FOR(i, 2, n + 1) {
    if (i - 1 > idx) {
      li[i] = idx;
      continue;
    }
    if (idx == n) {
      li[i] = n;
      continue;
    }
    ca += s[i - 1].a - s[i - 1].b + s[i].b - s[i].a;
    while (ca > 0 && idx < n) {
      ++idx;
      ca += s[idx + 1].a - s[idx + 1].b - c[idx];
    }
    li[i] = idx;
  }
}

int ff = n + 1;

bool judge(int x) {
  --x;
  FOR(i, 1, n + 1) {
    LL lim = L - s[i].a;
    if (li[i] <= x)
      continue;
    if (i > x && sum[x] >= lim)
      return true;
    if (i <= x && sum[x + 1] - s[i].a + s[i].b >= lim)
      return true;
  }
  return false;
}

int main() {
  while (~scanf("%d%lld", &n, &L)) {
    LL mx = -1;
    FOR(i, 1, n + 1)
    scanf("%lld%lld", &s[i].a, &s[i].b), mx = max(mx, s[i].a);
    s[n + 1].a = s[n + 1].b = 0;
    FOR(i, 1, n + 1) scanf("%lld", c + i);
    if (mx >= L) {
      printf("1\\n");
      continue;
    }
    sort(s + 1, s + n + 1);
    ff = n;
    FOR(i, 1, n + 1) if (s[i].a <= s[i].b) {
      ff = i;
      break;
    }
    sum[0] = 0;
    FOR(i, 1, n + 1) sum[i] = sum[i - 1] + s[i].a - s[i].b;
    Init();
    int l = 1, r = ff;
    if (l > r) {
      printf("-1\\n");
      continue;
    }
    while (l < r) {
      int mid = (l + r) >> 1;
      if (judge(mid))
        r = mid;
      else
        l = mid + 1;
    }
    if (judge(l))
      printf("%d\\n", l);
    else
      printf("-1\\n");
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstring>

typedef long long i64;
typedef std::pair<int, int> Info;

const int N = 100000 + 10;
const i64 INF = 0x3f3f3f3f3f3f3fLL;

int n, m, c[N];

Info info[N];
i64 x[N], y[N], u[N], v[N];

i64 table[20][N];

i64 rmq(int l, int r) {
  int k = 31 - __builtin_clz(r - l + 1);
  return std::min(table[k][l], table[k][r - (1 << k) + 1]);
}

int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    info[i] = Info(a - b, a);
  }
  std::sort(info + 1, info + n + 1);
  std::reverse(info + 1, info + n + 1);
  int ans = n + 1;
  for (int i = 1; i <= n; ++i)
    scanf("%d", &c[i]);
  for (int i = 1; i <= n; ++i)
    x[i] = x[i - 1] + std::max(info[i].first, 0), y[i] = y[i - 1] + c[i];
  for (int i = 1; i <= n; ++i)
    u[i] = x[i] - y[i], v[i] = x[i] - y[i - 1];
  u[0] = INF;
  for (int i = 1; i <= n; ++i)
    u[i] = std::min(u[i - 1], u[i]);
  memset(table, 0x3f, sizeof table);
  for (int i = 1; i <= n; ++i)
    table[0][i] = v[i];
  for (int i = 1; i < 20; ++i)
    for (int j = 1; j + (1 << i) - 1 <= n; ++j)
      table[i][j] = std::min(table[i - 1][j], table[i - 1][j + (1 << (i - 1))]);
  for (int i = 1; i <= n; ++i) {
    int t = info[i].second;
    if (x[i - 1] + t >= m) {
      int p = std::lower_bound(x, x + i, m - t) - x;
      if (u[p] > 0)
        ans = std::min(ans, p + 1);
    } else {
      int d = std::max(info[i].first, 0);
      int p = std::lower_bound(x + i + 1, x + n + 1, m - t + d) - x;
      if (p > n)
        continue;
      if (u[i - 1] > 0 && *std::min_element(v + i + 1, v + p + 1) - d > 0)
        ans = std::min(ans, p);
    }
  }
  printf("%d\\n", ans <= n ? ans : -1);
  return 0;
}