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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pb push_back
#define f(i, x, y) for (int i = x; i < y; i++)
#define FORV(it, A)                                                            \\
  for (vector<int>::iterator it = A.begin(); it != A.end(); it++)
#define FORS(it, A) for (set<int>::iterator it = A.begin(); it != A.end(); it++)
#define quad(x) (x) * (x)
#define mp make_pair
#define clr(x, y) memset(x, y, sizeof x)
#define fst first
#define snd second
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;

#define N 100000
ll S[N], v[N];
int pd[N];
int W, n;

inline ll teto(ll a, ll b) {
  return ((a - 1) / b) + 1;
  // if (a%b == 0) return a/b;
  // return a/b+1;
}

/*int solve (int E){
        pd[n] = 0;
        pd[n-1] = 1;
        for (int i = n-2; i >= 0; i--){
                int ini = i, fim = n-1;
                while (ini < fim-1){
                        int mid = ((ini+fim)>>1);
                        ll s = S[mid];
                        if (i != 0) s -= S[i-1];
                        if (s+mid-i <= W) ini = mid;
                        else fim = mid-1;
                }
                int y;
                ll s = S[fim];
                if (i != 0) s -= S[i-1];
                if (s+fim-i <= W) y = fim;
                else y = ini;
                ini = i+1, fim = y;
                while (ini < fim){
                        int mid = ((ini+fim)>>1);
                        ll s = S[mid];
                        if (i != 0) s -= S[i-1];
                        if (teto(W-s, mid-i) <= E) fim = mid; //TODO
                        else ini = mid+1;
                }
                s = S[y];
                if (i != 0) s -= S[i-1];
                int soma;
                if (teto(W-s, y-i) > E) soma = 0; //TODO
                else soma = pd[ini+1]-pd[y+2];
                if (y == n-1) soma = 1;
                pd[i] = pd[i+1];
                if (soma != 0) pd[i]++;
        }
        return pd[0]-pd[1];
}*/

ll V(int a, int b) {
  ll s = S[b];
  if (a != 0)
    s -= S[a - 1];
  return teto(W - s, b - a);
}

bool cabe(int a, int b) {
  int mid = b, i = a;
  ll s = S[mid];
  if (i != 0)
    s -= S[i - 1];
  return (s + mid - i <= W);
}

int solve(int E) {
  pd[n] = 0;
  pd[n - 1] = 1;
  int ini = n - 1, fim = n - 1;
  for (int i = n - 2; i >= 0; i--) {
    while (fim >= i) {
      if (cabe(i, fim))
        break;
      fim--;
    }
    int s;
    ini = min(ini, fim);
    if (V(i, fim) > E)
      s = 0;
    else {
      while (ini > i) {
        if (ini == i + 1 || V(i, ini - 1) > E)
          break;
        ini--;
      }
      s = pd[ini + 1] - pd[fim + 2];
    }
    pd[i] = pd[i + 1];
    if (fim == n - 1)
      s = 1;
    if (s)
      pd[i]++;
    // printf("->i = %d ini = %d fim = %d s = %d %d\\n", i,ini, fim, s, pd[i]);
  }
  return pd[0] - pd[1];
}

int main() {
  while (1) {
    cin >> W >> n;
    if (W + n == 0)
      break;
    f(i, 0, n) cin >> S[i];
    f(i, 1, n) S[i] += S[i - 1];
    int ini = 1, fim = W / 2 + 1;
    // cout << solve(1) << endl; break;
    while (ini < fim) {
      int mid = (ini + fim) / 2;
      if (solve(mid))
        fim = mid;
      else
        ini = mid + 1;
    }
    printf("%d\\n", ini);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define pb push_back
#define f(i, x, y) for (int i = x; i < y; i++)
#define FORV(it, A)                                                            \\
  for (vector<int>::iterator it = A.begin(); it != A.end(); it++)
#define FORS(it, A) for (set<int>::iterator it = A.begin(); it != A.end(); it++)
#define quad(x) (x) * (x)
#define mp make_pair
#define clr(x, y) memset(x, y, sizeof x)
#define fst first
#define snd second
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;

#define N 100000
ll S[N], v[N];
int pd[N];
int W, n;

inline ll teto(ll a, ll b) {
  return ((a - 1) / b) + 1;
  // if (a%b == 0) return a/b;
  // return a/b+1;
}

int solve(int E) {
  pd[n] = 0;
  pd[n - 1] = 1;
  for (int i = n - 2; i >= 0; i--) {
    int ini = i, fim = n - 1;
    while (ini < fim - 1) {
      int mid = ((ini + fim) >> 1);
      ll s = S[mid];
      if (i != 0)
        s -= S[i - 1];
      if (s + mid - i <= W)
        ini = mid;
      else
        fim = mid - 1;
    }
    int y;
    ll s = S[fim];
    if (i != 0)
      s -= S[i - 1];
    if (s + fim - i <= W)
      y = fim;
    else
      y = ini;
    ini = i + 1, fim = y;
    while (ini < fim) {
      int mid = ((ini + fim) >> 1);
      ll s = S[mid];
      if (i != 0)
        s -= S[i - 1];
      if (teto(W - s, mid - i) <= E)
        fim = mid; // TODO
      else
        ini = mid + 1;
    }
    s = S[y];
    if (i != 0)
      s -= S[i - 1];
    int soma;
    if (teto(W - s, y - i) > E)
      soma = 0; // TODO
    else
      soma = pd[ini + 1] - pd[y + 2];
    if (y == n - 1)
      soma = 1;
    pd[i] = pd[i + 1];
    if (soma != 0)
      pd[i]++;
  }
  return pd[0] - pd[1];
}

int main() {
  while (1) {
    cin >> W >> n;
    if (W + n == 0)
      break;
    f(i, 0, n) cin >> S[i];
    f(i, 1, n) S[i] += S[i - 1];
    int ini = 1, fim = W / 2 + 1;
    while (ini < fim) {
      int mid = (ini + fim) / 2;
      if (solve(mid))
        fim = mid;
      else
        ini = mid + 1;
    }
    printf("%d\\n", ini);
  }
  return 0;
}