[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;
}