Problem p04051 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define mod 1000000007
using namespace std;
/* AGC_1 E.BBQ Hard
   The answer is sigma(1<=i,j<=N,f(Ai+Aj,Bi+Bj)),
   while f(a,b)=C(a+b,a).
   Unfortunately,O(n^2) solution will get a TLE.
   So consider the geometric meaning for the answer.
   f(a,b) is equal to the way to go from (0,0) to (a,b).
   So f(Ai+Aj,Bi+Bj) equals to the way to go from (-Ai,-Bi) to (Aj,Bj).
   Do simple DP to solve it.
   And what's more,
   if the total answer is X,
   ans=(X-sigma(1<=i<=N,f(Ai*2,Bi*2)))/2,
   and f(Ai*2,Bi*2) can be got by pre-calculating the C(a,b).
*/
int a[200005], b[200005], n;
int f[8005][4006];
int main() {
  int i, j;
  scanf("%d", &n);
  for (i = 1; i <= n; i++) {
    scanf("%d%d", &a[i], &b[i]);
    f[2005 - a[i]][2005 - b[i]]++;
  }
  for (i = 1; i <= 4005; i++) {
    for (j = 1; j <= 4005; j++) {
      f[i][j] = f[i][j] + f[i - 1][j] + f[i][j - 1];
      while (f[i][j] >= mod) {
        f[i][j] -= mod;
      }
    }
  }
  int ans = 0;
  for (i = 1; i <= n; i++) {
    ans += f[2005 + a[i]][2005 + b[i]];
    while (ans >= mod) {
      ans -= mod;
    }
  }
  memset(f, 0, sizeof(f));
  f[0][0] = 1;
  for (i = 1; i <= 8000; i++) {
    f[i][0] = 1;
    f[i][i] = 1;
    for (j = 1; j < i; j++) {
      f[i][j] = f[i - 1][j] + f[i - 1][j - 1];
      while (f[i][j] >= mod) {
        f[i][j] -= mod;
      }
    }
  }
  for (i = 1; i <= n; i++) {
    ans -= f[2 * (a[i] + b[i])][a[i] * 2];
    while (ans < 0) {
      ans += mod;
    }
  }
  if (ans % 2 == 1) {
    ans += mod;
  }
  printf("%d", ans / 2);
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define mod 1000000007
using namespace std;
/* AGC_1 E.BBQ Hard
   The answer is sigma(1<=i,j<=N,f(Ai+Aj,Bi+Bj)),
   while f(a,b)=C(a+b,a).
   Unfortunately,O(n^2) solution will get a TLE.
   So consider the geometric meaning for the answer.
   f(a,b) is equal to the way to go from (0,0) to (a,b).
   So f(Ai+Aj,Bi+Bj) equals to the way to go from (-Ai,-Bi) to (Aj,Bj).
   Do simple DP to solve it.
   And what's more,
   if the total answer is X,
   ans=(X-sigma(1<=i<=N,f(Ai*2,Bi*2)))/2,
   and f(Ai*2,Bi*2) can be got by pre-calculating the C(a,b).
*/
int a[200005], b[200005], n;
int f[8005][4006];
int main() {
  int i, j;
  scanf("%d", &n);
  for (i = 1; i <= n; i++) {
    scanf("%d%d", &a[i], &b[i]);
    f[2005 - a[i]][2005 - b[i]]++;
  }
  for (i = 1; i <= 4005; i++) {
    for (j = 1; j <= 4005; j++) {
      f[i][j] = f[i][j] + f[i - 1][j] + f[i][j - 1];
      while (f[i][j] >= mod) {
        f[i][j] -= mod;
      }
    }
  }
  int ans = 0;
  for (i = 1; i <= n; i++) {
    ans += f[2005 + a[i]][2005 + b[i]];
    while (ans >= mod) {
      ans -= mod;
    }
  }
  memset(f, 0, sizeof(f));
  f[0][0] = 1;
  for (i = 1; i <= 8000; i++) {
    f[i][0] = 1;
    f[i][i] = 1;
    for (j = 1; j < i && j <= 4000; j++) {
      f[i][j] = f[i - 1][j] + f[i - 1][j - 1];
      while (f[i][j] >= mod) {
        f[i][j] -= mod;
      }
    }
  }
  for (i = 1; i <= n; i++) {
    ans -= f[2 * (a[i] + b[i])][a[i] * 2];
    while (ans < 0) {
      ans += mod;
    }
  }
  if (ans % 2 == 1) {
    ans += mod;
  }
  printf("%d", ans / 2);
  return 0;
}