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

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

ll W, N;
ll x[50000];
ll xsum[50010];
int dp[50010];

// [l, r]
ll minw(int l, int r) {
  ll sum = xsum[r + 1] - xsum[l] + (r - l);
  if (sum > W)
    return -1;
  ll rem = W - (xsum[r + 1] - xsum[l]);
  return (rem + (r - l - 1)) / (r - l);
}

bool check(int w) {
  memset(dp, 0, sizeof dp);
  dp[0] = 1;
  int cnt = 0;
  int L = 0, R = 0;
  for (int i = 1; i < N; i++) {
    while (L < i && minw(L, i) == -1) {
      if (dp[L])
        cnt--;
      L++;
    }
    while (R < i && minw(R, i) <= w) {
      if (dp[R])
        cnt++;
      R++;
    }
    // assert(minw(L, i) <= w && minw(R, i) <= w);
    if (cnt) {
      dp[i + 1] = 1;
      // ???????????????????????????????????°ok
      ll sum = xsum[N] - xsum[i + 1] + max(0LL, N - i - 2);
      if (i == N - 1 || sum <= W)
        return true;
    } else {
      dp[i + 1] = 0;
    }
  }
  return false;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
#ifdef LOCAL
  std::ifstream in("in");
  std::cin.rdbuf(in.rdbuf());
#endif

  while (cin >> W >> N, W + N) {
    for (int i = 0; i < N; i++) {
      cin >> x[i];
      xsum[i + 1] = xsum[i] + x[i];
    }

    ll sum = xsum[N] + N - 1;
    if (sum <= W) {
      cout << 1 << endl;
      continue;
    }

    int ng = 0, ok = W;
    while (abs(ng - ok) > 1) {
      int mid = (ng + ok) / 2;
      if (check(mid))
        ok = mid;
      else
        ng = mid;
    }
    cout << ok << endl;
  }
}

Error: TLE

Fixed submission:

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

ll W, N;
ll x[50000];
ll xsum[50010];
int dp[50010];
int trueSum[50010];

// [l, r]
ll minw(int l, int r) {
  ll sum = xsum[r + 1] - xsum[l] + (r - l);
  if (sum > W)
    return -1;
  ll rem = W - (xsum[r + 1] - xsum[l]);
  return (rem + (r - l - 1)) / (r - l);
}

bool check(int w) {
  memset(trueSum, 0, sizeof trueSum);
  trueSum[1] = 1;
  memset(dp, 0, sizeof dp);
  dp[0] = 1;
  for (int i = 1; i < N; i++) {
    int L, R;
    {
      int ng = -1, ok = i - 1;
      while (abs(ng - ok) > 1) {
        int mid = (ng + ok) / 2;
        int mw = minw(mid, i);
        if (mw != -1)
          ok = mid;
        else
          ng = mid;
      }
      L = ok;
      if (minw(L, i) > w) {
        trueSum[i + 2] = trueSum[i + 1];
        continue;
      }
    }
    {
      int ok = L, ng = i;
      while (abs(ng - ok) > 1) {
        int mid = (ng + ok) / 2;
        int mw = minw(mid, i);
        if (mw <= w)
          ok = mid;
        else
          ng = mid;
      }
      R = ok;
    }
    assert(minw(L, i) <= w && minw(R, i) <= w);
    int s = trueSum[R + 1] - trueSum[L];
    if (s >= 1) {
      dp[i + 1] = 1;
      trueSum[i + 2] = trueSum[i + 1] + 1;
      // ???????????????????????????????????°ok
      ll sum = xsum[N] - xsum[i + 1] + (N - i - 2);
      if (sum <= W)
        return true;
    } else {
      trueSum[i + 2] = trueSum[i + 1];
    }
  }
  return false;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
#ifdef LOCAL
  std::ifstream in("in");
  std::cin.rdbuf(in.rdbuf());
#endif

  while (cin >> W >> N, W + N) {
    for (int i = 0; i < N; i++) {
      cin >> x[i];
      xsum[i + 1] = xsum[i] + x[i];
    }

    ll sum = xsum[N] + N - 1;
    if (sum <= W) {
      cout << 1 << endl;
      continue;
    }

    int ng = 0, ok = W;
    while (abs(ng - ok) > 1) {
      int mid = (ng + ok) / 2;
      if (check(mid))
        ok = mid;
      else
        ng = mid;
    }
    cout << ok << endl;
  }
}