[ACG001E]BBQ Hard

ACG001E BBQ Hard

给定两个数组 求\(\begin{align*}\sum_{i=1}^n\sum_{j=i+1}^n\binom{a_i+b_i+a_j+b_j}{a_i+a_j} \end{align*}\)

由上面可以将\(\begin{align*}\binom{a_i+b_i+a_j+b_j}{a_i+a_j}\end{align*}\)转化为从点\((-b_i,-a_i)\)走到\((b_j,a_j)\)

\(f[i][j]\)即为各个起点走到它的方案数 递推可得

然后\(ans+=\sum_{i=1}^nf[a[i]][b[i]]\) 再减去自己走到自己的情况 最后除\(2\)

注意阶乘预处理要处理\(M<<2\)

==把组合变为走格子的形式很有用吖!

void Mod(ll &x){x=(x>=P)?x-P:x;}
ll C(int x,int y){return (fac[x]*ifac[y]%P)*ifac[x-y]%P;}
ll qpow(ll x,ll y){
	ll ret=1ll;
	while(y){
		if(y&1) ret=ret*x%P;
		x=x*x%P,y>>=1;
	}
	return ret;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
	rd(n);
	for(int i=1;i<=n;++i) rd(a[i]),rd(b[i]),++f[M-a[i]][M-b[i]];
	for(int i=1;i<=(M<<1);++i)
		for(int j=1;j<=(M<<1);++j)
			f[i][j]+=f[i-1][j],Mod(f[i][j]),f[i][j]+=f[i][j-1],Mod(f[i][j]);
	fac[0]=fac[1]=1ll;
	for(int i=2;i<=(M<<2);++i) fac[i]=fac[i-1]*(ll)i%P;
	ifac[M<<2]=qpow(fac[M<<2],P-2);
	for(int i=(M<<2);i;--i) ifac[i-1]=ifac[i]*i%P;
	for(int i=1;i<=n;++i) ans+=f[M+a[i]][M+b[i]],Mod(ans),ans+=(P-C(((a[i]+b[i])<<1),(a[i]<<1))),Mod(ans);
	printf("%lld",ans*inv2%P);
    return 0; 
}
posted @ 2019-10-09 19:19  委屈的咸鱼鱼鱼鱼  阅读(195)  评论(0编辑  收藏  举报