AGC001 E - BBQ Hard [组合数]

这题就是要求

\(\sum_{i=1}^{n} \sum_{j=i+1}^{n} C(a_i+a_j+b_i+b_j,a_i+a_j)\)

考虑搞一搞,\(C(a_i+a_j+b_i+b_j,a_i+a_j)\)的意义等同于从 \((-a_j,-b_j)\) 走到 \((a_i,b_i)\)的方案数
因而 \(其他的走到(a_i,b_i)\)的步数就等于所有的加起来走到\((a_i,b_i)\)
然后就可以了

考虑多余的部分

\(\sum_{i=1}^{n} \sum_{j=i+1}^{n} C(a_i+a_j+b_i+b_j,a_i+a_j)\)
\(=\frac{\sum_{i=1}^{n} \sum_{j=1}^{n} C(a_i+a_j+b_i+b_j,a_i+a_j)-\sum_{i=1}^{n} C(a_i+a_i,b_i+b_i)}{2}\)
逆元搞一搞,没了。

#include
using namespace std ;
#define rep(i , j , n) for(register int i = j ; i <= n ; i ++)
#define int long long 
int n ;
const int N = 2e5 + 10 ;
int a[N] , b[N] ;
const int S = 2e3 + 1 ;
const int M = 4e3 + 20 ;
int dp[M][M] ;
int fac[S << 2] ;
const int mod = 1e9 + 7 ;
int qpow(int x , int y) {
    int ans = 1 ;
    for( ; y ; y >>= 1 , x = x * x % mod) 
        if(y & 1) ans = ans * x % mod ;
    return ans ;
}
int inv(int x) {
    return qpow(x , mod - 2) ;
}
int C(int x , int y) {
    return fac[x] % mod * inv(fac[y]) % mod * inv(fac[x - y]) % mod ;
}
signed main() {
    ios :: sync_with_stdio(false) ;
    cin.tie(0) ;
    cout.tie(0) ;
    cin >> n ;
    fac[0] = 1 ;
    rep(i , 1 , S << 2) fac[i] = fac[i - 1] * i % mod ;
    rep(i , 1 , n) cin >> a[i] >> b[i] ;
    rep(i , 1 , n) ++ dp[S - a[i]][S - b[i]] ;
    rep(i , 1 , S << 1) rep(j , 1 , S << 1) {
        dp[i][j] = (dp[i][j] + dp[i][j - 1]) % mod ;
        dp[i][j] = (dp[i][j] + dp[i - 1][j]) % mod ;
    }
    int ans = 0 ;
    rep(i , 1 , n) (ans += dp[S + a[i]][S + b[i]]) %= mod ;
    rep(i , 1 , n) {
        ans = (ans - C(a[i] + b[i] + a[i] + b[i] , a[i] + a[i]) + mod) % mod ;
    }
    ans = (ans * inv(2)) % mod ;
    cout << ans << '\n' ;
    return 0 ;
}

你可能感兴趣的:(AGC001 E - BBQ Hard [组合数])