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

#include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

int w, n;
int x[50005];
bool dp[50005];

bool C(int v) {
  memset(dp, false, sizeof(dp));
  dp[0] = true;
  int l = 0, r = 0;
  int cnt = 0;
  int wmax = 0, wmin = 0;
  for (int i = 0; i < n; i++) {
    while (r < i && wmax + x[i] >= w) {
      if (dp[r])
        cnt++;
      wmax -= x[r] + v;
      r++;
    }
    if (i == (n - 1)) {
      while (r <= i) {
        if (dp[r])
          cnt++;
        r++;
      }
    }
    while (l < r && wmin + x[i] > w) {
      if (dp[l])
        cnt--;
      wmin -= x[l] + 1;
      l++;
    }
    wmax += x[i] + v;
    wmin += x[i] + 1;
    if (cnt > 0) {
      dp[i + 1] = true;
    }
  }
  return (dp[n] || dp[n - 1]);
}

void solve() {
  int l = 0, r = w;
  while (l + 1 < r) {
    int mid = (l + r) / 2;
    if (C(mid))
      r = mid;
    else
      l = mid;
  }
  printf("%d\\n", r);
}

int main(void) {
  while (1) {
    scanf("%d%d", &w, &n);
    if (w == 0 && n == 0)
      break;
    for (int i = 0; i < n; i++) {
      scanf("%d", &x[i]);
    }
    solve();
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

class segtree {
public:
  static const int N = 1 << 16;
  int dp[1 << 17];
  int lazy[1 << 17];
  segtree() {
    memset(dp, 0, sizeof(dp));
    memset(lazy, 0, sizeof(lazy));
  }
  void init() {
    memset(dp, 0, sizeof(dp));
    memset(lazy, 0, sizeof(lazy));
  }

  void lazy_eval(int k) {
    dp[k] += lazy[k];
    if (k < N - 1) {
      lazy[k * 2 + 1] += lazy[k];
      lazy[k * 2 + 2] += lazy[k];
    }
    lazy[k] = 0;
  }
  void lazy_upd(int k) { dp[k] = min(dp[k * 2 + 1], dp[k * 2 + 2]); }
  void update(int a, int b, int v, int k = 0, int l = 0, int r = N) {
    lazy_eval(k);
    if (b <= l || r <= a)
      return;
    if (a <= l && r <= b) {
      lazy[k] += v;
      lazy_eval(k);
      return;
    }
    int mid = (l + r) / 2;
    update(a, b, v, k * 2 + 1, l, mid);
    update(a, b, v, k * 2 + 2, mid, r);
    lazy_upd(k);
  }

  int query(int a, int b, int k = 0, int l = 0, int r = N) {
    lazy_eval(k);
    if (b <= l || r <= a)
      return 514514;
    if (a <= l && r <= b)
      return dp[k];
    int mid = (l + r) / 2;
    int vl = query(a, b, k * 2 + 1, l, mid);
    int vr = query(a, b, k * 2 + 2, mid, r);
    lazy_upd(k);
    return min(vl, vr);
  }
};

int w, n;
int x[50005];
segtree wmax, wmin;
bool dp[50005];

bool C(int v) {
  wmax.init();
  wmin.init();
  memset(dp, false, sizeof(dp));
  dp[0] = true;
  int l = 0, r = 0;
  int cnt = 0;
  for (int i = 0; i < n; i++) {
    while (r <= i && wmax.query(r, r + 1) + x[i] >= w) {
      if (dp[r])
        cnt++;
      r++;
    }
    if (i == (n - 1)) {
      while (r <= i) {
        if (dp[r])
          cnt++;
        r++;
      }
    }
    while (l < r && wmin.query(l, l + 1) + x[i] > w) {
      if (dp[l])
        cnt--;
      l++;
    }
    wmin.update(0, i + 1, x[i] + 1);
    wmax.update(0, i + 1, x[i] + v);
    if (cnt > 0) {
      dp[i + 1] = true;
    }
  }
  return dp[n];
}

void solve() {
  int l = 0, r = w;
  while (l + 1 < r) {
    int mid = (l + r) / 2;
    if (C(mid))
      r = mid;
    else
      l = mid;
  }
  printf("%d\\n", r);
}

int main(void) {
  while (1) {
    scanf("%d%d", &w, &n);
    if (w == 0 && n == 0)
      break;
    for (int i = 0; i < n; i++) {
      scanf("%d", &x[i]);
    }
    solve();
  }
  return 0;
}