Problem p04051 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#define maxn 301005
#define maxm 2018
#define maxr 101005
#define M 1000000007
#define ll long long int
#define rep(i, l, r) for (register int i = l; i <= r; i++)
#define per(i, r, l) for (register int i = r; i >= l; i--)
#define gc()                                                                   \
  ((p1 == p2 &&                                                                \
    (p2 = (p1 = buffer) + fread(buffer, 1, maxr, stdin), p1 == p2))            \
       ? EOF                                                                   \
       : *p1++)
using namespace std;

char buffer[maxn], *p1, *p2;
template <class T> void read(T &x) {
  char ch = gc();
  x = 0;
  bool f = 1;
  while (!('0' <= ch && ch <= '9') && ch != '-')
    ch = gc();
  if (ch == '-')
    f = 0, ch = gc();
  while ('0' <= ch && ch <= '9')
    x = (x << 1) + (x << 3) + ch - '0', ch = gc();
  if (!f)
    x = -x;
}

int n;
int x[maxn], y[maxn], num[maxm][maxm];
bool vis[maxm << 1][maxm << 1];
int dp[maxm << 1][maxm << 1];
int DP(int x, int y) {
  if (x >= maxm << 1 || y >= maxm << 1)
    return 0;
  if (vis[x][y])
    return dp[x][y];
  vis[x][y] = 1;
  int &ans = dp[x][y];
  if (x >= 1 + maxm && y >= 1 + maxm)
    ans = num[x - maxm][y - maxm];
  return ans = (ans + DP(x + 1, y) + DP(x, y + 1)) % M;
}
ll fac[maxn], ifac[maxn], inv[maxn];
ll cal(int m, int n) {
  return (m < n) ? 0 : fac[m] * ifac[n] % M * ifac[m - n] % M;
}
void init() {
  fac[0] = ifac[0] = inv[1] = 1;
  rep(i, 1, maxn - 1) fac[i] = fac[i - 1] * i % M;
  rep(i, 2, maxn - 1) inv[i] = M - M / i * inv[M % i] % M;
  rep(i, 1, maxn - 1) ifac[i] = ifac[i - 1] * inv[i] % M;
}
int main() {
#ifndef ONLINE_JUDGE
  freopen("bbq.in", "r", stdin);
#endif
  init();
  read(n);
  rep(i, 1, n) read(x[i]), read(y[i]), num[x[i]][y[i]]++;
  int ans = 0;
  rep(i, 1, n)(ans += DP(maxm - x[i], maxm - y[i])) %= M,
      (ans += M - cal(2 * x[i] + 2 * y[i], 2 * x[i])) %= M;
  ans = (ll)(M + 1) / 2 * ans % M;
  printf("%d", ans);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#define maxn 301005
#define maxm 2018
#define maxr 101005
#define M 1000000007
#define ll long long int
#define rep(i, l, r) for (register int i = l; i <= r; i++)
#define per(i, r, l) for (register int i = r; i >= l; i--)
#define gc()                                                                   \
  ((p1 == p2 &&                                                                \
    (p2 = (p1 = buffer) + fread(buffer, 1, maxr, stdin), p1 == p2))            \
       ? EOF                                                                   \
       : *p1++)
using namespace std;

char buffer[maxn], *p1, *p2;
template <class T> void read(T &x) {
  char ch = gc();
  x = 0;
  bool f = 1;
  while (!('0' <= ch && ch <= '9') && ch != '-')
    ch = gc();
  if (ch == '-')
    f = 0, ch = gc();
  while ('0' <= ch && ch <= '9')
    x = (x << 1) + (x << 3) + ch - '0', ch = gc();
  if (!f)
    x = -x;
}

int n;
int x[maxn], y[maxn], num[maxm][maxm];
bool vis[maxm << 1][maxm << 1];
int dp[maxm << 1][maxm << 1];
int DP(int x, int y) {
  if (x >= maxm << 1 || y >= maxm << 1)
    return 0;
  if (vis[x][y])
    return dp[x][y];
  vis[x][y] = 1;
  int &ans = dp[x][y];
  if (x >= 1 + maxm && y >= 1 + maxm)
    ans = num[x - maxm][y - maxm];
  return ans = (ans + DP(x + 1, y) + DP(x, y + 1)) % M;
}
ll fac[maxn], ifac[maxn], inv[maxn];
ll cal(int m, int n) {
  return (m < n) ? 0 : fac[m] * ifac[n] % M * ifac[m - n] % M;
}
void init() {
  fac[0] = ifac[0] = inv[1] = 1;
  rep(i, 1, maxn - 1) fac[i] = fac[i - 1] * i % M;
  rep(i, 2, maxn - 1) inv[i] = M - M / i * inv[M % i] % M;
  rep(i, 1, maxn - 1) ifac[i] = ifac[i - 1] * inv[i] % M;
}
int main() {
  init();
  read(n);
  rep(i, 1, n) read(x[i]), read(y[i]), num[x[i]][y[i]]++;
  int ans = 0;
  rep(i, 1, n)(ans += DP(maxm - x[i], maxm - y[i])) %= M,
      (ans += M - cal(2 * x[i] + 2 * y[i], 2 * x[i])) %= M;
  ans = (ll)(M + 1) / 2 * ans % M;
  printf("%d", ans);
  return 0;
}