Problem p03825 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
using Int = long long;
template <typename T1, typename T2> inline void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <typename T1, typename T2> inline void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

template <typename T, T MOD = 1000000007> struct Mint {
  T v;
  Mint() : v(0) {}
  Mint(signed v) : v(v) {}
  Mint(long long t) {
    v = t % MOD;
    if (v < 0)
      v += MOD;
  }

  Mint pow(long long k) {
    Mint res(1), tmp(v);
    while (k) {
      if (k & 1)
        res *= tmp;
      tmp *= tmp;
      k >>= 1;
    }
    return res;
  }

  Mint inv() { return pow(MOD - 2); }

  Mint &operator+=(Mint a) {
    v += a.v;
    if (v >= MOD)
      v -= MOD;
    return *this;
  }
  Mint &operator-=(Mint a) {
    v += MOD - a.v;
    if (v >= MOD)
      v -= MOD;
    return *this;
  }
  Mint &operator*=(Mint a) {
    v = 1LL * v * a.v % MOD;
    return *this;
  }
  Mint &operator/=(Mint a) { return (*this) *= a.inv(); }

  Mint operator+(Mint a) const { return Mint(v) += a; };
  Mint operator-(Mint a) const { return Mint(v) -= a; };
  Mint operator*(Mint a) const { return Mint(v) *= a; };
  Mint operator/(Mint a) const { return Mint(v) /= a; };

  Mint operator-() { return v ? MOD - v : v; }

  bool operator==(const Mint a) const { return v == a.v; }
  bool operator!=(const Mint a) const { return v != a.v; }
  bool operator<(const Mint a) const { return v < a.v; }
};
// INSERT ABOVE HERE
const int MAX = 4040;
using M = Mint<int>;
M dp[MAX][MAX];
signed main() {
  int n, m, k;
  cin >> n >> m >> k;

  for (int i = 0; i < MAX; i++)
    for (int j = 0; j < MAX; j++)
      dp[i][j] = 0;

  dp[0][0] = 1;

  M ans = 0;
  for (int i = 0; i + 1 < MAX; i++) {
    for (int j = 0; j + k < MAX; j++) {
      for (int a = 0; a < k; a++) {
        dp[i + 1][j + a] += dp[i][j];
        if (a == 0)
          continue;
        int l = i * (k - 1) + k;
        int x = j + a, y = l - x;
        if (x > m || y > n)
          continue;
        if ((m - x) % (k - 1))
          continue;
        if ((n - y) % (k - 1))
          continue;
        ans += dp[i][j];
      }
    }
  }
  cout << ans.v << endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using Int = long long;
template <typename T1, typename T2> inline void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <typename T1, typename T2> inline void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

template <typename T, T MOD = 1000000007> struct Mint {
  T v;
  Mint() : v(0) {}
  Mint(signed v) : v(v) {}
  Mint(long long t) {
    v = t % MOD;
    if (v < 0)
      v += MOD;
  }

  Mint pow(long long k) {
    Mint res(1), tmp(v);
    while (k) {
      if (k & 1)
        res *= tmp;
      tmp *= tmp;
      k >>= 1;
    }
    return res;
  }

  Mint inv() { return pow(MOD - 2); }

  Mint &operator+=(Mint a) {
    v += a.v;
    if (v >= MOD)
      v -= MOD;
    return *this;
  }
  Mint &operator-=(Mint a) {
    v += MOD - a.v;
    if (v >= MOD)
      v -= MOD;
    return *this;
  }
  Mint &operator*=(Mint a) {
    v = 1LL * v * a.v % MOD;
    return *this;
  }
  Mint &operator/=(Mint a) { return (*this) *= a.inv(); }

  Mint operator+(Mint a) const { return Mint(v) += a; };
  Mint operator-(Mint a) const { return Mint(v) -= a; };
  Mint operator*(Mint a) const { return Mint(v) *= a; };
  Mint operator/(Mint a) const { return Mint(v) /= a; };

  Mint operator-() { return v ? MOD - v : v; }

  bool operator==(const Mint a) const { return v == a.v; }
  bool operator!=(const Mint a) const { return v != a.v; }
  bool operator<(const Mint a) const { return v < a.v; }
};
// INSERT ABOVE HERE
const int MAX = 4040;
using M = Mint<int>;
M dp[MAX][MAX];
signed main() {
  int n, m, k;
  cin >> n >> m >> k;

  for (int i = 0; i < MAX; i++)
    for (int j = 0; j < MAX; j++)
      dp[i][j] = 0;

  dp[0][0] = 1;

  M ans = 0;
  for (int i = 0; i + 1 < MAX; i++) {
    M res = 0;
    for (int j = 0; j < MAX; j++) {
      if (j - k >= 0)
        res -= dp[i][j - k];
      res += dp[i][j];
      dp[i + 1][j] += res;
    }
  }
  for (int i = 0; i + 1 < MAX; i++) {
    int l = i * (k - 1) + k;
    for (int j = 0; j <= m; j++) {
      int a = (m - j) % (k - 1);
      if (a == 0)
        a = k - 1;
      int x = j + a, y = l - x;
      if (x > m || y > n)
        continue;
      if ((m - x) % (k - 1))
        continue;
      if ((n - y) % (k - 1))
        continue;
      ans += dp[i][j];
    }
  }
  cout << ans.v << endl;
  return 0;
}