n<=2∗105
作为一个丝薄只会n^2。。。
事实上,可以发现
C(ai+bi+aj+bj,ai+aj)
是长宽分别为ai+aj,bi+bj的矩形的从左下角走到右上角的步数,那么我们dp一下,去掉走到自己的点数,然后除以2就好了。
#include<cstdio>
#include<algorithm>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int mo=1e9+7;
const int N=1e5+5;
int n,a[N],b[N];
int fac[10005],ans;
typedef long long ll;
ll f[4005][4005];
inline ll pow(int a,int b)
{
ll ret=1;
while (b)
{
if (b&1)ret=1ll*ret*a%mo;
a=1ll*a*a%mo;
b>>=1;
}
return ret;
}
inline ll C(int x,int y)
{
return 1ll*fac[x]%mo*pow(fac[y],mo-2)%mo*pow(fac[x-y],mo-2)%mo;
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%d",&n);
int mx=0;
fo(i,1,n)scanf("%d%d",&a[i],&b[i]),mx=max(mx,max(a[i],b[i]));
fo(i,1,n)f[a[i]+mx][b[i]+mx]++;
fac[0]=1;
fo(i,1,8005)fac[i]=1ll*fac[i-1]*i%mo;
ll ans=0;
fd(i,mx*2,0)
fd(j,mx*2,0)
f[i][j]=(f[i][j]+f[i+1][j]+f[i][j+1])%mo;
fo(i,1,n)
ans=(ans+f[mx-a[i]][mx-b[i]]%mo-C(a[i]*2+b[i]*2,a[i]*2)%mo+mo)%mo;
printf("%lld\n",ans*pow(2,mo-2)%mo);
}