Problem p04051 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define ll long long
#define file(s)                                                                \
  freopen(s ".in", "r", stdin);                                                \
  freopen(s ".out", "w", stdout);
using namespace std;
template <typename T> inline void chkmax(T &x, T y) { x = (x > y) ? x : y; }
template <typename T> inline void chkmin(T &x, T y) { x = (x < y) ? x : y; }
template <typename T> inline void read(T &x) {
  int _ = 1;
  x = 0;
  char __ = getchar();
  while (!isdigit(__)) {
    if (__ == '-')
      _ = -1;
    __ = getchar();
  }
  while (isdigit(__)) {
    x = (x << 3) + (x << 1) + (__ ^ '0');
    __ = getchar();
  }
  x *= _;
}
template <typename T> inline void write(T x) {
  if (x == 0) {
    puts("0");
    return;
  }
  if (x < 0)
    x = -x, putchar('-');
  int LEN = 0, y[20];
  while (x) {
    y[LEN++] = x % 10;
    x /= 10;
  }
  for (register int i = LEN - 1; i >= 0; --i)
    putchar(y[i] + '0');
  puts("");
}
const int maxm = 2e5 + 10, mod = 1e9 + 7, maxn = 8e3 + 10;
int n;
int a[maxm], b[maxm];
int inv[maxn], fac[maxn];
int dp[maxn][maxn];
int ans;

inline int qpow(int x, int y) {
  int ret = 1;
  for (; y; y >>= 1) {
    if (y & 1)
      ret = 1ll * ret * x % mod;
    x = 1ll * x * x % mod;
  }
  return ret;
}
inline int C(int x, int y) {
  if (x < y)
    return 0;
  return 1ll * fac[x] * inv[y] % mod * inv[x - y] % mod;
}

inline void init() {
  read(n);
  int N = maxn - 5;
  fac[0] = 1, inv[0] = 1;
  for (register int i = 1; i <= N; ++i)
    fac[i] = 1ll * fac[i - 1] * i % mod;
  inv[N] = qpow(fac[N], mod - 2);
  for (register int i = N; i >= 1; --i)
    inv[i - 1] = 1ll * inv[i] * i % mod;
}
int main() {
#ifndef ONLINE_JUDGE
  file("AT1983");
#endif
  init();
  for (register int i = 1; i <= n; ++i) {
    read(a[i]), read(b[i]);
    dp[2002 - a[i]][2002 - b[i]]++;
  }
  for (register int i = 1; i <= 4002; ++i)
    for (register int j = 1; j <= 4002; ++j)
      (dp[i][j] += (dp[i - 1][j] + dp[i][j - 1]) % mod) %= mod;
  for (register int i = 1; i <= n; ++i)
    (ans += (dp[a[i] + 2002][b[i] + 2002] - C((a[i] + b[i]) * 2, a[i] * 2))) %=
        mod;
  cout << 1ll * (mod + 1) / 2 * (ans + mod) % mod << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define ll long long
#define file(s)                                                                \
  freopen(s ".in", "r", stdin);                                                \
  freopen(s ".out", "w", stdout);
using namespace std;
template <typename T> inline void chkmax(T &x, T y) { x = (x > y) ? x : y; }
template <typename T> inline void chkmin(T &x, T y) { x = (x < y) ? x : y; }
template <typename T> inline void read(T &x) {
  int _ = 1;
  x = 0;
  char __ = getchar();
  while (!isdigit(__)) {
    if (__ == '-')
      _ = -1;
    __ = getchar();
  }
  while (isdigit(__)) {
    x = (x << 3) + (x << 1) + (__ ^ '0');
    __ = getchar();
  }
  x *= _;
}
template <typename T> inline void write(T x) {
  if (x == 0) {
    puts("0");
    return;
  }
  if (x < 0)
    x = -x, putchar('-');
  int LEN = 0, y[20];
  while (x) {
    y[LEN++] = x % 10;
    x /= 10;
  }
  for (register int i = LEN - 1; i >= 0; --i)
    putchar(y[i] + '0');
  puts("");
}
const int maxm = 2e5 + 10, mod = 1e9 + 7, maxn = 8e3 + 10;
int n;
int a[maxm], b[maxm];
int inv[maxn], fac[maxn];
int dp[maxn][maxn];
int ans;

inline int qpow(int x, int y) {
  int ret = 1;
  for (; y; y >>= 1) {
    if (y & 1)
      ret = 1ll * ret * x % mod;
    x = 1ll * x * x % mod;
  }
  return ret;
}
inline int C(int x, int y) {
  if (x < y)
    return 0;
  return 1ll * fac[x] * inv[y] % mod * inv[x - y] % mod;
}

inline void init() {
  read(n);
  int N = maxn - 5;
  fac[0] = 1, inv[0] = 1;
  for (register int i = 1; i <= N; ++i)
    fac[i] = 1ll * fac[i - 1] * i % mod;
  inv[N] = qpow(fac[N], mod - 2);
  for (register int i = N; i >= 1; --i)
    inv[i - 1] = 1ll * inv[i] * i % mod;
}
int main() {
  init();
  for (register int i = 1; i <= n; ++i) {
    read(a[i]), read(b[i]);
    dp[2002 - a[i]][2002 - b[i]]++;
  }
  for (register int i = 1; i <= 4002; ++i)
    for (register int j = 1; j <= 4002; ++j)
      (dp[i][j] += (dp[i - 1][j] + dp[i][j - 1]) % mod) %= mod;
  for (register int i = 1; i <= n; ++i)
    (ans += (dp[a[i] + 2002][b[i] + 2002] - C((a[i] + b[i]) * 2, a[i] * 2))) %=
        mod;
  cout << 1ll * (mod + 1) / 2 * (ans + mod) % mod << endl;
  return 0;
}