Problem p04051 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define REP(i, st, ed) for (int i = st, i##end = ed; i <= i##end; ++i)
#define DREP(i, st, ed) for (int i = st, i##end = ed; i >= i##end; --i)
int read() {
  int x = 0, f = 1;
  char c = getchar();
  while ((c < '0') || (c > '9')) {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while ((c >= '0') && (c <= '9'))
    x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
  return x * f;
}
const int maxn = 200005, maxm = 4005, mod = 1e9 + 7;
int n, x[maxn], y[maxn];
int dp[maxm][maxm];
int fac[maxm << 1], ifac[maxm << 1];
int ksm(int x, int y) {
  int res = 1;
  while (y) {
    if (y & 1)
      res = 1ll * res * x % mod;
    x = 1ll * x * x % mod, y >>= 1;
  }
  return res;
}
void get_fac() {
  fac[0] = 1;
  REP(i, 1, 8000) fac[i] = 1ll * fac[i - 1] * i % mod;
  ifac[8000] = ksm(fac[8000], mod - 2);
  DREP(i, 8000, 1) ifac[i - 1] = 1ll * ifac[i] * i % mod;
}
int C(int x, int y) { return 1ll * fac[x] * ifac[y] % mod * ifac[x - y] % mod; }
int main() {
#ifndef ONLINE_JUDGE
  freopen("a.in", "r", stdin);
  freopen("a.out", "w", stdout);
#endif
  get_fac();
  n = read();
  REP(i, 1, n) {
    x[i] = read(), y[i] = read();
    ++dp[2000 - x[i]][2000 - y[i]];
  }
  REP(i, 0, 4000)
  REP(j, 0, 4000) {
    if (i)
      (dp[i][j] += dp[i - 1][j]) %= mod;
    if (j)
      (dp[i][j] += dp[i][j - 1]) %= mod;
  }
  long long ans = 0;
  REP(i, 1, n)
  ans += dp[2000 + x[i]][2000 + y[i]] - C(2 * x[i] + 2 * y[i], 2 * x[i]);
  ((ans %= mod) += mod) %= mod;
  ans = ans * 500000004 % mod;
  printf("%d\n", ans);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define REP(i, st, ed) for (int i = st, i##end = ed; i <= i##end; ++i)
#define DREP(i, st, ed) for (int i = st, i##end = ed; i >= i##end; --i)
int read() {
  int x = 0, f = 1;
  char c = getchar();
  while ((c < '0') || (c > '9')) {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while ((c >= '0') && (c <= '9'))
    x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
  return x * f;
}
const int maxn = 200005, maxm = 4005, mod = 1e9 + 7;
int n, x[maxn], y[maxn];
int dp[maxm][maxm];
int fac[maxm << 1], ifac[maxm << 1];
int ksm(int x, int y) {
  int res = 1;
  while (y) {
    if (y & 1)
      res = 1ll * res * x % mod;
    x = 1ll * x * x % mod, y >>= 1;
  }
  return res;
}
void get_fac() {
  fac[0] = 1;
  REP(i, 1, 8000) fac[i] = 1ll * fac[i - 1] * i % mod;
  ifac[8000] = ksm(fac[8000], mod - 2);
  DREP(i, 8000, 1) ifac[i - 1] = 1ll * ifac[i] * i % mod;
}
int C(int x, int y) { return 1ll * fac[x] * ifac[y] % mod * ifac[x - y] % mod; }
int main() {
  get_fac();
  n = read();
  REP(i, 1, n) {
    x[i] = read(), y[i] = read();
    ++dp[2000 - x[i]][2000 - y[i]];
  }
  REP(i, 0, 4000)
  REP(j, 0, 4000) {
    if (i)
      (dp[i][j] += dp[i - 1][j]) %= mod;
    if (j)
      (dp[i][j] += dp[i][j - 1]) %= mod;
  }
  long long ans = 0;
  REP(i, 1, n)
  ans += dp[2000 + x[i]][2000 + y[i]] - C(2 * x[i] + 2 * y[i], 2 * x[i]);
  ((ans %= mod) += mod) %= mod;
  ans = ans * 500000004 % mod;
  printf("%d\n", ans);
  return 0;
}