Problem p03825 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define Rep(i, a, b) for (register int i = (a); i <= int(b); ++i)
#define Dep(i, a, b) for (register int i = (a); i >= int(b); --i)
#define rep(i, a, b) for (register int i = (a); i < int(b); ++i)
#define mem(x, v) memset(x, v, sizeof(x))
#define gc getchar
#define pc putchar
#define fi first
#define se second
#define debug(x) cout << #x " = " << x << endl;
#define pp(x, y) cout << "pp: " << x << " " << y << endl;
inline ll read() {
  register ll x = 0, f = 1;
  register char c = gc();
  for (; !isdigit(c); c = gc())
    if (c == '-')
      f = -1;
  for (; isdigit(c); c = gc())
    x = (x << 1) + (x << 3) + (c ^ 48);
  return x * f;
}
#define rd read
void write(ll x) {
  if (x < 0)
    x = -x, pc('-');
  if (x >= 10)
    write(x / 10);
  putchar(x % 10 + '0');
}
void writeln(ll x) {
  write(x);
  puts("");
}
const int maxn = 100005;
const int mod = 1e9 + 7;
int f[2005][2005][2], s[2005];
int n, m, K, ans;
int main() {
  n = rd(), m = rd(), K = rd();
  m -= 1, K -= 1;
  f[0][0][0] = 1; // 0表示这一位选0,1表示这一位选择不选择0
  // 显然长度不会超过2*max(n,m)位
  for (int i = 1; i <= max(n, m) << 1; ++i) {
    Rep(j, 0, n) s[j + 1] =
        ((s[j] + f[i - 1][j][0]) % mod + f[i - 1][j][1]) % mod;
    Rep(j, 0, n) {
      f[i][j][0] =
          (f[i - 1][j][0] + f[i - 1][j][1]) % mod; //(s[j+1]-s[j]+mod)%mod;
      int k = max(0, j - K + 1 - 1);
      f[i][j][1] = (s[j] - s[k] + mod) % mod;
    }
    Rep(j, 0, n) {
      if (j % K == n % K && (i * K - j) % K == m % K && i * K - j <= m)
        ans = (ans + f[i][j][1]) % mod;
    }
  }
  writeln(ans);
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define Rep(i, a, b) for (register int i = (a); i <= int(b); ++i)
#define Dep(i, a, b) for (register int i = (a); i >= int(b); --i)
#define rep(i, a, b) for (register int i = (a); i < int(b); ++i)
#define mem(x, v) memset(x, v, sizeof(x))
#define gc getchar
#define pc putchar
#define fi first
#define se second
#define debug(x) cout << #x " = " << x << endl;
#define pp(x, y) cout << "pp: " << x << " " << y << endl;
inline ll read() {
  register ll x = 0, f = 1;
  register char c = gc();
  for (; !isdigit(c); c = gc())
    if (c == '-')
      f = -1;
  for (; isdigit(c); c = gc())
    x = (x << 1) + (x << 3) + (c ^ 48);
  return x * f;
}
#define rd read
void write(ll x) {
  if (x < 0)
    x = -x, pc('-');
  if (x >= 10)
    write(x / 10);
  putchar(x % 10 + '0');
}
void writeln(ll x) {
  write(x);
  puts("");
}
const int maxn = 100005;
const int mod = 1e9 + 7;
int f[4005][2005][2], s[2005];
int n, m, K, ans;
int main() {
  n = rd(), m = rd(), K = rd();
  m -= 1, K -= 1;
  f[0][0][0] = 1; // 0表示这一位选0,1表示这一位选择不选择0
  // 显然长度不会超过2*max(n,m)位
  for (int i = 1; i <= max(n, m) << 1; ++i) {
    Rep(j, 0, n) s[j + 1] =
        ((s[j] + f[i - 1][j][0]) % mod + f[i - 1][j][1]) % mod;
    Rep(j, 0, n) {
      f[i][j][0] =
          (f[i - 1][j][0] + f[i - 1][j][1]) % mod; //(s[j+1]-s[j]+mod)%mod;
      int k = max(0, j - K + 1 - 1);
      f[i][j][1] = (s[j] - s[k] + mod) % mod;
    }
    Rep(j, 0, n) {
      if (j % K == n % K && (i * K - j) % K == m % K && i * K - j <= m)
        ans = (ans + f[i][j][1]) % mod;
    }
  }
  writeln(ans);
  return 0;
}