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

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

struct BIT {
  int size;
  ll t[100000];
  void init(int n) {
    size = n + 5;
    for (int i = 0; i <= size; i++)
      t[i] = 0;
  }

  ll sum(int i) {
    ll res = 0;
    while (0 < i) {
      res += t[i];
      i -= (i & -i);
    }
    return res;
  }
  ll sum(int a, int b) {
    if (a > b)
      return 0;
    if (a <= 1)
      return sum(b);
    else
      return sum(b) - sum(a - 1);
  }
  void add(int i, ll x) {
    while (i < size) {
      t[i] += x;
      i += (i & -i);
    }
  }
};

ll W, N;
BIT X, DP;

int judge(int l, int r, ll M) {
  if (l == r)
    return -1;
  ll d = X.sum(l, r);
  if (d + (r - l) > W)
    return 1;
  if (d + (ll)(r - l) * M < W)
    return -1;
  return 0;
}

int getlower(int i, ll M) {
  int left = i + 1, right = N, mid;
  while (left < right) {
    mid = (left + right) / 2;
    if (judge(i, mid, M) == -1)
      left = mid + 1;
    else
      right = mid;
  }
  return left;
}

int getupper(int i, ll M) {
  int left = i + 1, right = N + 1, mid;
  while (right - left > 1) {
    mid = (left + right) / 2;
    if (judge(i, mid, M) <= 0)
      left = mid;
    else
      right = mid;
  }
  return left;
}

bool check(int M) {
  DP.init(N + 1);
  DP.add(N + 1, 1);
  int fi = N;
  int se = N;

  for (int i = N; i >= 1; i--) {
    if (X.sum(i, N) + N - i <= W) {
      DP.add(i, 1);
      continue;
    }
    while (judge(i, fi - 1, M) >= 0)
      fi--;
    while (judge(i, se, M) == 1)
      se--;

    if (DP.sum(fi + 1, se + 1) > 0)
      DP.add(i, 1);
  }
  return (DP.sum(1) == 1);
}

int main() {
  while (1) {
    scanf("%lld %lld", &W, &N);
    if (W == 0 && N == 0)
      break;
    X.init(N + 5);
    for (int i = 1; i <= N; i++) {
      ll x;
      scanf("%lld", &x);
      X.add(i, x);
    }

    int L = 1, R = W - 2, M;
    while (L < R) {
      M = (L + R) / 2;
      if (check(M))
        R = M;
      else
        L = M + 1;
    }
    printf("%d\\n", L);
  }
  return 0;
}

Error: TLE

Fixed submission:

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

struct BIT {
  int size;
  ll t[100000];
  void init(int n) {
    size = n + 5;
    for (int i = 0; i <= size; i++)
      t[i] = 0;
  }

  ll sum(int i) {
    ll res = 0;
    while (0 < i) {
      res += t[i];
      i -= (i & -i);
    }
    return res;
  }
  ll sum(int a, int b) {
    if (a > b)
      return 0;
    if (a <= 1)
      return sum(b);
    else
      return sum(b) - sum(a - 1);
  }
  void add(int i, ll x) {
    while (i < size) {
      t[i] += x;
      i += (i & -i);
    }
  }
};

#define MAX_N 50005
ll W, N;
BIT X, DP;

int judge(int l, int r, ll M) {
  if (l == r)
    return -1;
  ll d = X.sum(l, r);
  if (d + (r - l) > W)
    return 1;
  if (d + (ll)(r - l) * M < W)
    return -1;
  return 0;
}

int getlower(int i, ll M) {
  int left = i + 1, right = N, mid;
  while (left < right) {
    mid = (left + right) / 2;
    if (judge(i, mid, M) == -1)
      left = mid + 1;
    else
      right = mid;
  }
  return left;
}

int getupper(int i, ll M) {
  int left = i + 1, right = N + 1, mid;
  while (right - left > 1) {
    mid = (left + right) / 2;
    if (judge(i, mid, M) <= 0)
      left = mid;
    else
      right = mid;
  }
  return left;
}

bool check(int M) {
  DP.init(N + 1);
  DP.add(N + 1, 1);

  for (int i = N; i >= 1; i--) {
    if (X.sum(i, N) + N - i <= W) {
      DP.add(i, 1);
      continue;
    }
    int fi = getlower(i, M);
    int se = getupper(i, M);
    if (DP.sum(fi + 1, se + 1) > 0)
      DP.add(i, 1);
  }
  return (DP.sum(1) == 1);
}

int main() {
  while (1) {
    scanf("%lld %lld", &W, &N);
    if (W == 0 && N == 0)
      break;
    X.init(N + 5);
    for (int i = 1; i <= N; i++) {
      ll x;
      scanf("%lld", &x);
      X.add(i, x);
    }

    int L = 1, R = W - 2, M;
    while (L < R) {
      M = (L + R) / 2;
      if (check(M))
        R = M;
      else
        L = M + 1;
    }
    printf("%d\\n", L);
  }
  return 0;
}