AGC001E
\[\sum_{i=1}^n\sum_{j=i+1}^n {A_i+A_j+B_i+B_j\choose A_i+A_j}
\]
\(50pts\)暴力很好打不讲
根据组合意义
\(\large x+y\choose x\)表示从\((0,0)\)走到\((x,y)\),每次只能向上向右的路径数 $poj1942 $ 原题
把式子转化成了\((0,0)\)到\((A_i+A_j,B_i+B_j)\)的路径
高能,换个思维
平移一下,求\((-A_i,-B_i)\)到\((A_j,B_j)\)的路径
\((-A_i,-B_i)\)为起点,求\((x,y)\)有多少路径到它
考虑dp,令\(dp[i][j]\)为从\((i,j)\)到所有\((-A_i,-B_i)\)的路径条数之和
初始化,枚举\(i\),\(dp[-A_i][-B_i]=1\),转移\(dp[x][y]=dp[x-1][y]+dp[x][y-1]\)
把\(dp[A_i][B_i]\)求和
题目求的是\(i\not=j\),所以减去一个\(\large2A_i+2B_i\choose 2A_i\)
又因为要\(i<j\),所有结果再除以二
\(O((\max(A_i)+\max(B_i))^2+N)\)
代码比较简单 咕咕咕咕
int a[MAX],b[MAX],n,ans;
int f[4500][4500];
int inv[9000],jc[9000],jv[9000];
int C(int n,int m){return 1ll*jc[n]*jv[m]%MOD*jv[n-m]%MOD;}
int main()
{
n=read();
for(int i=1;i<=n;++i)a[i]=read(),b[i]=read();
for(int i=1;i<=n;++i)f[py-a[i]][py-b[i]]+=1;
for(int i=1;i<=py*2;++i)
for(int j=1;j<=py*2;++j)
add(f[i][j],f[i-1][j]),add(f[i][j],f[i][j-1]);
inv[0]=inv[1]=jc[0]=jv[0]=1;
for(int i=1;i<py<<2;++i)jc[i]=1ll*jc[i-1]*i%MOD;
for(int i=2;i<py<<2;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1;i<py<<2;++i)jv[i]=1ll*jv[i-1]*inv[i]%MOD;
for(int i=1;i<=n;++i)add(ans,f[a[i]+py][b[i]+py]);
for(int i=1;i<=n;++i)add(ans,MOD-C(2*(a[i]+b[i]),2*a[i]));
ans=1ll*ans*inv[2]%MOD;printf("%d\n",ans);
return 0;
}