Problem p04051 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#define eps 1e-8
#define fo(i, l, r) for (int i = l; i <= r; i++)
#define of(i, l, r) for (int i = l; i >= r; i--)
#define fe(i, u) for (int i = head[u]; i; i = e[i].next)
using namespace std;
typedef long long ll;
inline int rd() {
  int x = 0, f = 1;
  char ch = getchar();
  for (; ch < '0' || ch > '9'; ch = getchar())
    if (ch == '-')
      f = -1;
  for (; ch >= '0' && ch <= '9'; ch = getchar())
    x = x * 10 + ch - '0';
  return x * f;
}
const int N = 200010, mod = 1000000007;
int n, a[N], b[N], fac[8010], rfac[8010], ans = 0;
int f[4010][4010];

inline int pls(int a, int b) { return a + b >= mod ? a + b - mod : a + b; }
inline int mns(int a, int b) { return a < b ? a - b + mod : a - b; }
inline int mul(int a, int b) { return (ll)a * b % mod; }
inline int pwr(int x, int k) {
  int res = 1;
  for (; k; k >>= 1, x = mul(x, x))
    if (k & 1)
      res = mul(res, x);
  return res;
}
inline int _inv(int x) { return pwr(x, mod - 2); }
inline int C(int n, int m) {
  return n < m ? 0 : mul(fac[n], mul(rfac[m], rfac[n - m]));
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("inb.txt", "r", stdin);
#endif
  fac[0] = 1;
  fo(i, 1, 8001) fac[i] = mul(fac[i - 1], i);
  rfac[8001] = _inv(fac[8001]);
  of(i, 8001, 1) rfac[i - 1] = mul(rfac[i], i);
  n = rd();
  fo(i, 1, n) a[i] = rd(), b[i] = rd(),
              f[2000 - a[i]][2000 - b[i]] = pls(f[2000 - a[i]][2000 - b[i]], 1);
  //	f[0][0]=1;
  fo(i, 0, 4000) fo(j, 0, 4000) {
    if (i)
      f[i][j] = pls(f[i][j], f[i - 1][j]);
    if (j)
      f[i][j] = pls(f[i][j], f[i][j - 1]);
  }
  //	cout<<f[3][3]<<endl;
  fo(i, 1, n) ans = pls(ans, f[2000 + a[i]][2000 + b[i]]);
  //	fo(i,1,n)cout<<f[2000+a[i]][2000+b[i]]<<' ';cout<<endl;
  fo(i, 1, n) ans = mns(ans, C((a[i] + b[i]) << 1, a[i] << 1));
  ans = mul(ans, rfac[2]);
  printf("%d\n", ans);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#define eps 1e-8
#define fo(i, l, r) for (int i = l; i <= r; i++)
#define of(i, l, r) for (int i = l; i >= r; i--)
#define fe(i, u) for (int i = head[u]; i; i = e[i].next)
using namespace std;
typedef long long ll;
inline int rd() {
  int x = 0, f = 1;
  char ch = getchar();
  for (; ch < '0' || ch > '9'; ch = getchar())
    if (ch == '-')
      f = -1;
  for (; ch >= '0' && ch <= '9'; ch = getchar())
    x = x * 10 + ch - '0';
  return x * f;
}
const int N = 200010, mod = 1000000007;
int n, a[N], b[N], fac[8010], rfac[8010], ans = 0;
int f[4010][4010];

inline int pls(int a, int b) { return a + b >= mod ? a + b - mod : a + b; }
inline int mns(int a, int b) { return a < b ? a - b + mod : a - b; }
inline int mul(int a, int b) { return (ll)a * b % mod; }
inline int pwr(int x, int k) {
  int res = 1;
  for (; k; k >>= 1, x = mul(x, x))
    if (k & 1)
      res = mul(res, x);
  return res;
}
inline int _inv(int x) { return pwr(x, mod - 2); }
inline int C(int n, int m) {
  return n < m ? 0 : mul(fac[n], mul(rfac[m], rfac[n - m]));
}

int main() {
  fac[0] = 1;
  fo(i, 1, 8001) fac[i] = mul(fac[i - 1], i);
  rfac[8001] = _inv(fac[8001]);
  of(i, 8001, 1) rfac[i - 1] = mul(rfac[i], i);
  n = rd();
  fo(i, 1, n) a[i] = rd(), b[i] = rd(),
              f[2000 - a[i]][2000 - b[i]] = pls(f[2000 - a[i]][2000 - b[i]], 1);
  //	f[0][0]=1;
  fo(i, 0, 4000) fo(j, 0, 4000) {
    if (i)
      f[i][j] = pls(f[i][j], f[i - 1][j]);
    if (j)
      f[i][j] = pls(f[i][j], f[i][j - 1]);
  }
  //	cout<<f[3][3]<<endl;
  fo(i, 1, n) ans = pls(ans, f[2000 + a[i]][2000 + b[i]]);
  //	fo(i,1,n)cout<<f[2000+a[i]][2000+b[i]]<<' ';cout<<endl;
  fo(i, 1, n) ans = mns(ans, C((a[i] + b[i]) << 1, a[i] << 1));
  ans = mul(ans, rfac[2]);
  printf("%d\n", ans);
  return 0;
}