【题解】AT1983 BBQ Hard (格路)
题目就是要求
\[ \sum_{i=1}^n \sum _{j>i}^n {a_i+b_i+a_j+b_j \choose a_i+a_j} \]
其中\(n\le 2\times 10^5,a_i,b_i\in [1,2000]\)
这个式子有很强的组合一样,一个熟练的选手应该发现这个组合数是\(x+y\choose s\)的形式,也就是对应上了格路问题。这个问题等价于从若干\((-a_i,-b_i)\)到\((a_j,b_j)\)的方案数。格路问题另一个解法是值域的DP,于是我们可以简单DP得到所有\((-a_i,-b_i)\)到\((a_j,b_j)\)的方案数的和。
但是有一个边界是,不能\((i->j)\),并且一个\((i,j)\)只能算一次。所以我单独算一下\(i=j\)的所以情况的方案,减去之后在除以二。
//@winlere
#include
#include
#include
#include
#include
#define DEBUG(s,a) cerr<<#s" = "<<(s)<<" \n"[(a)==1]
using namespace std; typedef long long ll; char __buf[1<<18],*__c=__buf,*__ed=__buf;
inline int qr(){
int ret=0,f=0,c=getchar();
while(!isdigit(c))f|=c==45,c=getchar();
while(isdigit(c)) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int maxn=8000+5;
const int mod=1e9+7;
int dp[maxn][maxn],N,n,jc[maxn],inv[maxn],A[200000+1],B[200000+1];
inline int MOD(const int&x){return x>=mod?x-mod:x;}
inline int MOD(const int&x,const int&y){return 1ll*x*y%mod;}
inline int ksm(const int&ba,const int&p){
int ret=1;
for(int t=p,b=ba;t;t>>=1,b=MOD(b,b))
if(t&1) ret=MOD(ret,b);
return ret;
}
void pre(const int&n){
jc[0]=inv[0]=1;
for(int t=1;t<=n;++t) jc[t]=MOD(jc[t-1],t);
inv[n]=ksm(jc[n],mod-2);
for(int t=n-1;t;--t) inv[t]=MOD(inv[t+1],t+1);
for(int t=1;t<=n;++t) assert(MOD(inv[t],jc[t])==1);
}
int c(const int&n,const int&m){
if(n