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;
}
posted @ 2020-10-11 19:16  INFP  阅读(70)  评论(0编辑  收藏  举报