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

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <vector>

using namespace std;

#define TIMES(i, n) for (int i = 0; i < (n); ++i)

template <class Pred> int binsearch(const Pred &pred) {
  int val = 0;
  for (int bit = 17; bit >= 0; --bit) {
    const int next = val + (1 << bit);
    val = pred(next) ? next : val;
  }
  return val;
}

bool solve() {
  int W, N;
  scanf("%d %d", &W, &N);
  if (!W && !N)
    return false;

  vector<long long> sum(N + 2, 0);
  TIMES(i, N) {
    int v;
    scanf("%d", &v);
    sum[i + 1] = v;
    sum[i + 1] += sum[i];
  }
  sum[N + 1] = sum[N];

  vector<int> dp(N + 3, 0);
  int ans = binsearch([&](long long x) {
              if (x > W)
                return false;
              fill(dp.begin(), dp.end(), 0);
              dp[N + 2] = 0;
              dp[N + 1] = 1;
              for (int i = N; i > 0; --i) {
                const int mink = binsearch([&](int k) {
                                   if (i + k > N)
                                     return false;
                                   const long long len =
                                       (sum[i + k] - sum[i - 1]) + k * x;
                                   return len < W;
                                 }) +
                                 2;
                const int maxk = binsearch([&](int k) {
                                   if (i + k > N)
                                     return false;
                                   const long long len =
                                       (sum[i + k] - sum[i - 1]) + k;
                                   return len <= W;
                                 }) +
                                 1;
                // cout << x << ' ' << i << ' ' << mink << ' ' << maxk << endl;
                dp[i] = (i + maxk == N + 1) ||
                        (mink <= maxk && dp[i + mink] - dp[i + maxk + 1] > 0);
                // cout << dp[i] << endl;
                dp[i] += dp[i + 1];
              }
              return dp[1] - dp[2] == 0;
            }) +
            1;
  printf("%d\\n", ans);
  return true;
}

int main() {
  while (solve())
    ;
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <vector>

using namespace std;

#define TIMES(i, n) for (int i = 0; i < (n); ++i)

template <class Pred> int binsearch(const Pred &pred) {
  int val = 0;
  for (int bit = 20; bit >= 0; --bit) {
    const int next = val + (1 << bit);
    val = pred(next) ? next : val;
  }
  return val;
}

bool solve() {
  int W, N;
  scanf("%d %d", &W, &N);
  if (!W && !N)
    return false;

  vector<long long> sum(N + 2, 0);
  TIMES(i, N) {
    int v;
    scanf("%d", &v);
    sum[i + 1] = v;
    sum[i + 1] += sum[i];
  }
  sum[N + 1] = sum[N];

  vector<int> dp(N + 3, 0);
  int ans = binsearch([&](long long x) {
              if (x > W)
                return false;
              fill(dp.begin(), dp.end(), 0);
              dp[N + 2] = 0;
              dp[N + 1] = 1;
              for (int i = N; i > 0; --i) {
                const int mink = binsearch([&](int k) {
                                   if (i + k > N)
                                     return false;
                                   const long long len =
                                       (sum[i + k] - sum[i - 1]) + k * x;
                                   return len < W;
                                 }) +
                                 2;
                const int maxk = binsearch([&](int k) {
                                   if (i + k > N)
                                     return false;
                                   const long long len =
                                       (sum[i + k] - sum[i - 1]) + k;
                                   return len <= W;
                                 }) +
                                 1;
                // cout << x << ' ' << i << ' ' << mink << ' ' << maxk << endl;
                dp[i] = (i + maxk == N + 1) ||
                        (mink <= maxk && dp[i + mink] - dp[i + maxk + 1] > 0);
                // cout << dp[i] << endl;
                dp[i] += dp[i + 1];
              }
              return dp[1] - dp[2] == 0;
            }) +
            1;
  printf("%d\\n", ans);
  return true;
}

int main() {
  while (solve())
    ;
  return 0;
}