Problem p01452 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < ((int)(n)); i++)
#define reg(i, a, b) for (int i = ((int)(a)); i <= ((int)(b)); i++)
#define irep(i, n) for (int i = ((int)(n)) - 1; i >= 0; i--)
#define ireg(i, a, b) for (int i = ((int)(b)); i >= ((int)(a)); i--)
typedef long long int lli;
typedef pair<int, int> mp;
#define fir first
#define sec second
#define IINF INT_MAX
#define LINF LLONG_MAX
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define pque(type) priority_queue<type, vector<type>, greater<type>>
#define memst(a, b) memset(a, b, sizeof(a))

#define MOD ((lli)(1000000007))
lli mop(lli p, lli q) {
  lli res = 1, bp = p, b = 1;
  while (q) {
    if (q & b) {
      res = (res * bp) % MOD;
      q -= b;
    }
    bp = (bp * bp) % MOD;
    b *= 2;
  }
  return res;
}

lli inv(lli p) { return mop(p, MOD - 2); }

lli fdat[100005];

lli fact(int p) {
  if (fdat[p] >= 0)
    return fdat[p];
  lli res = 1;
  reg(i, 1, p) res = (res * i) % MOD;
  return (fdat[p] = res);
}

lli comb(lli p, lli q) {
  lli res = (((fact(p) * inv(fact(q))) % MOD) * inv(fact(p - q))) % MOD;
  return res;
}

lli nk(int p, int q) { // p+q susumi q modoru
  if (q <= 0)
    return 1;
  return (MOD + comb(p + 2 * q, q) - comb(p + q * 2, q - 1)) % MOD;
  //
}

int n, m, k;
int main(void) {

  memset(fdat, -1, sizeof(fdat));
  // printf("%lld\n",nk(2,1));
  // printf("%lld\n",nk(3,2));

  scanf("%d%d%d", &n, &m, &k);
  lli ans = 0;
  reg(i, 0, k) {
    lli na = comb(n + m + k * 2, n + i * 2);
    // printf("%lld\n",na);
    na = (na * nk(n, i)) % MOD;
    na = (na * nk(m, k - i)) % MOD;
    ans = (ans + na) % MOD;
  }

  printf("%lld\n", ans);

  return 0;
}

Fixed submission:
#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < ((int)(n)); i++)
#define reg(i, a, b) for (int i = ((int)(a)); i <= ((int)(b)); i++)
#define irep(i, n) for (int i = ((int)(n)) - 1; i >= 0; i--)
#define ireg(i, a, b) for (int i = ((int)(b)); i >= ((int)(a)); i--)
typedef long long int lli;
typedef pair<int, int> mp;
#define fir first
#define sec second
#define IINF INT_MAX
#define LINF LLONG_MAX
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define pque(type) priority_queue<type, vector<type>, greater<type>>
#define memst(a, b) memset(a, b, sizeof(a))

#define MOD ((lli)(1000000007))
lli mop(lli p, lli q) {
  lli res = 1, bp = p, b = 1;
  while (q) {
    if (q & b) {
      res = (res * bp) % MOD;
      q -= b;
    }
    bp = (bp * bp) % MOD;
    b *= 2;
  }
  return res;
}

lli inv(lli p) { return mop(p, MOD - 2); }

lli fdat[500005];

lli fact(int p) {
  if (fdat[p] >= 0)
    return fdat[p];
  lli res = 1;
  reg(i, 1, p) res = (res * i) % MOD;
  return (fdat[p] = res);
}

lli comb(lli p, lli q) {
  lli res = (((fact(p) * inv(fact(q))) % MOD) * inv(fact(p - q))) % MOD;
  return res;
}

lli nk(int p, int q) { // p+q susumi q modoru
  if (q <= 0)
    return 1;
  return (MOD + comb(p + 2 * q, q) - comb(p + q * 2, q - 1)) % MOD;
  //
}

int n, m, k;
int main(void) {

  memset(fdat, -1, sizeof(fdat));
  // printf("%lld\n",nk(2,1));
  // printf("%lld\n",nk(3,2));

  scanf("%d%d%d", &n, &m, &k);
  lli ans = 0;
  reg(i, 0, k) {
    lli na = comb(n + m + k * 2, n + i * 2);
    // printf("%lld\n",na);
    na = (na * nk(n, i)) % MOD;
    na = (na * nk(m, k - i)) % MOD;
    ans = (ans + na) % MOD;
  }

  printf("%lld\n", ans);

  return 0;
}