Problem p03859 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define mo 1000000007
using namespace std;
int fac[3010], nifac[3010], sum[3010], l[3010], r[3010], f[3010][3010];
bool bo[3010];
int getmi(int a, int x) {
  int ans = 1;
  while (x) {
    if (x & 1)
      ans = (long long)ans * a % mo;
    a = (long long)a * a % mo;
    x >>= 1;
  }
  return ans;
}
int C(int n, int m) {
  if ((m > n) || (n < 0) || (m < 0))
    return 0;
  return (long long)fac[n] * nifac[m] % mo * nifac[n - m] % mo;
}
int main() {
  freopen("in.txt", "r", stdin);
  int n, m;
  scanf("%d%d\n", &n, &m);
  fac[0] = nifac[0] = 1;
  for (int i = 1; i <= n; i++) {
    fac[i] = (long long)fac[i - 1] * i % mo;
    nifac[i] = getmi(fac[i], mo - 2);
  }
  for (int i = 1; i <= n; i++) {
    char ch = getchar();
    sum[i] = (ch == '1');
  }
  for (int i = 1; i <= m; i++)
    scanf("%d%d", &l[i], &r[i]);
  bo[1] = true;
  int ed = 1;
  for (int i = 2; i <= m; i++) {
    if (l[i] == l[ed]) {
      if (r[i] >= r[ed]) {
        bo[ed] = false;
        bo[i] = true;
        ed = i;
      }
      continue;
    }
    if (r[i] > r[ed]) {
      bo[i] = true;
      ed = i;
    }
  }
  int top = 0;
  for (int i = 1; i <= m; i++)
    if (bo[i]) {
      top++;
      l[top] = l[i];
      r[top] = r[i];
    }
  for (int i = 1; i <= top; i++)
    l[top + 1] = r[top] + 1;
  f[0][0] = 1;
  for (int i = 1; i <= top; i++)
    for (int j = r[i - 1] + 1; j < l[i]; j++)
      sum[j] = 0;
  for (int i = 1; i <= n; i++)
    sum[i] += sum[i - 1];

  for (int i = 1; i <= top; i++)
    for (int j = max(0, sum[r[i]] - max(0, (r[i] - l[i + 1] + 1)));
         j <= sum[r[i]]; j++) {
      // if (l[i]<=r[i-1])
      //{
      for (int k = max(0, l[i] - min(l[i + 1], r[i] + 1) + j);
           k <= min(sum[r[i - 1]], j); k++)
        f[i][j] = (f[i][j] + (long long)f[i - 1][k] *
                                 C(min(l[i + 1], r[i] + 1) - l[i], j - k)) %
                  mo;
      //}
      // else f[i][j]=f[i-1][sum[r[i-1]]];
      // cerr<<i<<' '<<j<<' '<<f[i][j]<<endl;
    }
  int ans = 0;
  for (int i = 0; i <= sum[r[top]]; i++)
    ans = (ans + f[top][i]) % mo;
  cout << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>
#define mo 1000000007
using namespace std;
int fac[3010], nifac[3010], sum[3010], l[3010], r[3010], f[3010][3010];
bool bo[3010];
int getmi(int a, int x) {
  int ans = 1;
  while (x) {
    if (x & 1)
      ans = (long long)ans * a % mo;
    a = (long long)a * a % mo;
    x >>= 1;
  }
  return ans;
}
int C(int n, int m) {
  if ((m > n) || (n < 0) || (m < 0))
    return 0;
  return (long long)fac[n] * nifac[m] % mo * nifac[n - m] % mo;
}
int main() {
  // freopen("in.txt","r",stdin);
  int n, m;
  scanf("%d%d\n", &n, &m);
  fac[0] = nifac[0] = 1;
  for (int i = 1; i <= n; i++) {
    fac[i] = (long long)fac[i - 1] * i % mo;
    nifac[i] = getmi(fac[i], mo - 2);
  }
  for (int i = 1; i <= n; i++) {
    char ch = getchar();
    sum[i] = (ch == '1');
  }
  for (int i = 1; i <= m; i++)
    scanf("%d%d", &l[i], &r[i]);
  bo[1] = true;
  int ed = 1;
  for (int i = 2; i <= m; i++) {
    if (l[i] == l[ed]) {
      if (r[i] >= r[ed]) {
        bo[ed] = false;
        bo[i] = true;
        ed = i;
      }
      continue;
    }
    if (r[i] > r[ed]) {
      bo[i] = true;
      ed = i;
    }
  }
  int top = 0;
  for (int i = 1; i <= m; i++)
    if (bo[i]) {
      top++;
      l[top] = l[i];
      r[top] = r[i];
    }
  for (int i = 1; i <= top; i++)
    l[top + 1] = r[top] + 1;
  f[0][0] = 1;
  for (int i = 1; i <= top; i++)
    for (int j = r[i - 1] + 1; j < l[i]; j++)
      sum[j] = 0;
  for (int i = 1; i <= n; i++)
    sum[i] += sum[i - 1];

  for (int i = 1; i <= top; i++)
    for (int j = max(0, sum[r[i]] - max(0, (r[i] - l[i + 1] + 1)));
         j <= sum[r[i]]; j++) {
      // if (l[i]<=r[i-1])
      //{
      for (int k = max(0, l[i] - min(l[i + 1], r[i] + 1) + j);
           k <= min(sum[r[i - 1]], j); k++)
        f[i][j] = (f[i][j] + (long long)f[i - 1][k] *
                                 C(min(l[i + 1], r[i] + 1) - l[i], j - k)) %
                  mo;
      //}
      // else f[i][j]=f[i-1][sum[r[i-1]]];
      // cerr<<i<<' '<<j<<' '<<f[i][j]<<endl;
    }
  int ans = 0;
  for (int i = 0; i <= sum[r[top]]; i++)
    ans = (ans + f[top][i]) % mo;
  cout << ans << endl;
}