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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <functional>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i <= (n); ++i)
#define all(c) (c).begin(), (c).end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl
int W, N, x[50000], sum[50001];
bool dp[50001];
int imos[50002];
bool can(int x) {
  rep(i, N + 1) dp[i] = false;
  dp[0] = true;
  imos[1] = 1;
  for (int i = 1; i <= N; i++) {
    int lb = 1, ub = i + 1;
    while (ub - lb > 1) {
      int m = (ub + lb) / 2;
      if (W - (sum[i] - sum[i - m]) >= m - 1)
        lb = m;
      else
        ub = m;
    }
    int r = lb;
    lb = 1, ub = i + 1;
    while (ub - lb > 1) {
      int m = (lb + ub) / 2;
      if (W - (sum[i] - sum[i - m]) <= (long long)(m - 1) * x)
        ub = m;
      else
        lb = m;
    }
    int l = ub;
    if (imos[i - l + 1] - imos[i - r] > 0)
      dp[i] = true;
    imos[i + 1] = imos[i] + (dp[i] ? 1 : 0);
  }
  for (int i = N; i >= 0; i--) {
    if (sum[N] - sum[i] + (N - 1 - i) > W)
      break;
    if (dp[i])
      return true;
  }
  return false;
}
int main() {
  while (true) {
    scanf("%d%d", &W, &N);
    if (W == 0)
      return 0;
    rep(i, N) scanf("%d", x + i);
    rep1(i, N) sum[i] = sum[i - 1] + x[i - 1];
    int ub = W / 2 + 1, lb = 0;
    while (ub - lb > 1) {
      int m = (ub + lb) / 2;
      if (can(m))
        ub = m;
      else
        lb = m;
    }
    cout << ub << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <functional>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i <= (n); ++i)
#define all(c) (c).begin(), (c).end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl
int W, N, x[50000], sum[50001];
bool can(int x) {
  bool dp[50001] = {};
  int imos[50002] = {};
  dp[0] = true;
  imos[1] = 1;
  for (int i = 2; i <= N; i++) {
    int lb = 1, ub = i + 1;
    while (ub - lb > 1) {
      int m = (ub + lb) / 2;
      if (W - (sum[i] - sum[i - m]) >= m - 1)
        lb = m;
      else
        ub = m;
    }
    int r = lb;
    lb = 1, ub = i + 1;
    while (ub - lb > 1) {
      int m = (lb + ub) / 2;
      if (W - (sum[i] - sum[i - m]) <= (long long)(m - 1) * x)
        ub = m;
      else
        lb = m;
    }
    int l = ub;
    if (imos[i - l + 1] - imos[i - r] > 0)
      dp[i] = true;
    imos[i + 1] = imos[i] + (dp[i] ? 1 : 0);
  }
  for (int i = N; i >= 0; i--) {
    if (sum[N] - sum[i] + (N - 1 - i) > W)
      break;
    if (dp[i])
      return true;
  }
  return false;
}
int main() {
  while (true) {
    scanf("%d%d", &W, &N);
    if (W == 0)
      return 0;
    rep(i, N) scanf("%d", x + i);
    rep1(i, N) sum[i] = sum[i - 1] + x[i - 1];
    int ub = W / 2, lb = 0;
    while (ub - lb > 1) {
      int m = (ub + lb) / 2;
      if (can(m))
        ub = m;
      else
        lb = m;
    }
    cout << ub << endl;
  }
}