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

#include <algorithm>
#include <stdio.h>
#include <string.h>
using namespace std;
int c[51000];
int bit[51000];
int getsum(int a, int b) {
  if (a)
    return getsum(0, b) - getsum(0, a - 1);
  int ret = 0;
  for (; b >= 0; b = (b & (b + 1)) - 1)
    ret += bit[b];
  return ret;
}
void add(int a, int b) {
  for (; a < 51000; a |= a + 1)
    bit[a] += b;
}
int sum[51000];
int main() {
  int a, b;
  while (scanf("%d%d", &a, &b), a) {
    for (int i = 0; i < b; i++)
      scanf("%d", c + i);
    for (int i = 0; i < b; i++)
      sum[i + 1] = sum[i] + c[i];
    int L = 0;
    int R = a;
    while (L + 1 < R) {
      int M = (L + R) / 2;
      for (int i = 0; i <= b + 1; i++)
        bit[i] = 0;
      add(0, 1);
      add(1, -1);
      for (int i = 0; i < b; i++) {
        if (!getsum(0, i))
          continue;
        if (sum[b] - sum[i] + b - i - 1 <= a) {
          //		printf("%d %d\\n",M,i);
          add(b, 1);
          break;
        }
        int l = i;
        int r = b;
        while (l + 1 < r) {
          int m = (l + r) / 2;
          if (M * (m - i - 1) >= a - (sum[m] - sum[i]))
            r = m;
          else
            l = m;
        }
        int v1 = r;
        //	if(v1-i-1>a-(sum[v1]-sum[i]))continue;
        l = i - 1;
        r = b;
        while (l + 1 < r) {
          int m = (l + r) / 2;
          if (m - i - 1 > a - (sum[m] - sum[i]))
            r = m;
          else
            l = m;
        }
        int v2 = l;
        //	printf("%d %d %d %d\\n",M,i,v1,v2);
        if (v1 <= v2) {
          add(v1, 1);
          add(v2 + 1, -1);
        }
      }
      if (getsum(0, b))
        R = M;
      else
        L = M;
    }
    printf("%d\\n", R);
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <stdio.h>
#include <string.h>
using namespace std;
int c[51000];
char segtree[131072];
int sz;
inline int query(int a) {
  a += sz;
  while (a) {
    if (segtree[a])
      return 1;
    a /= 2;
  }
  return 0;
}
void add(int a, int b, int c, int d, int e) {
  if (d < a || b < c)
    return;
  if (c <= a && b <= d) {
    segtree[e] = 1;
    return;
  }
  add(a, (a + b) / 2, c, d, e * 2);
  add((a + b) / 2 + 1, b, c, d, e * 2 + 1);
}
int sum[51000];
int main() {
  int a, b;
  while (scanf("%d%d", &a, &b), a) {
    sz = 1;
    while (sz < b + 1)
      sz *= 2;
    for (int i = 0; i < b; i++)
      scanf("%d", c + i);
    for (int i = 0; i < b; i++)
      sum[i + 1] = sum[i] + c[i];
    int L = 0;
    int R = a / 2;
    while (L + 1 < R) {
      int M = (L + R) / 2;
      memset(segtree, 0, sz * 2);
      // for(int i=0;i<sz*2;i++)segtree[i]=0;
      add(0, sz - 1, 0, 0, 1);
      for (int i = 0; i < b; i++) {
        if (!query(i))
          continue;
        if (sum[b] - sum[i] + b - i - 1 <= a) {
          add(0, sz - 1, b, b, 1);
          break;
        }
        int l = i;
        int r = b;
        while (l + 1 < r) {
          int m = (l + r) / 2;
          if (M * (m - i - 1) >= a - (sum[m] - sum[i]))
            r = m;
          else
            l = m;
        }
        int v1 = r;
        if (v1 - i - 1 > a - (sum[v1] - sum[i]))
          continue;
        l = i - 1;
        r = b;
        while (l + 1 < r) {
          int m = (l + r) / 2;
          if (m - i - 1 > a - (sum[m] - sum[i]))
            r = m;
          else
            l = m;
        }
        int v2 = l;
        if (v1 <= v2)
          add(0, sz - 1, v1, v2, 1);
      }
      if (query(b))
        R = M;
      else
        L = M;
    }
    printf("%d\\n", R);
  }
}