Gym - 103145A Matrix(组合数)

题目链接

解题思路

  考虑单独计算每个数的贡献,假设\([1,n]\)中的某个数对答案有贡献,则这一行其他的数都要比它大,所以这一行其他数一共有\(C(n^2-i, n-1)\)种选法,而这一行的方案数就是\(n! \times C(n^2-i, n-1)\),对于其他的数来说,不管它们是否小于\(n\),随意放置都不会影响这一行对答案的贡献,所以其他的数共有\((n^2-n)!\)种放置方案,一共有\(n\)行,所以我们枚举的数可以放\(n\)行中,答案再乘上\(n\)就是我们枚举的当前数字\(i\)的方案数。
  所以最终答案就是\(\sum_{i=1}^n n \times C(n^2-i, n-1) \times n! \times (n^2-n)!\)

代码

const int maxn = 5e3+10;
const int maxm = 5e3*5e3+10;
int fac[maxm], inv[maxm];
ll fp(ll x, ll y) {
    ll ans = 1;
    while(y) {
        if(y&1) ans = ans*x%MOD;
        x = x*x%MOD;
        y >>= 1;
    }
    return ans;
}
void init() {
    fac[0] = 1;
    for(int i = 1; i<maxm; ++i) fac[i] = 1LL*fac[i-1]*i%MOD;
    inv[maxm-1] = fp(fac[maxm-1], MOD-2);
    for(int i = maxm-2; i>=0; --i) inv[i] = 1LL*inv[i+1]*(i+1)%MOD;
}
int main() {
    IOS;
    init();
    int __; cin >> __;
    while(__--) {
        ll n; cin >> n;
        ll ans = 0;
        for (int i = 1; i<=n; ++i) {
            ll t = n*fac[n*n-i]%MOD*inv[n-1]%MOD*inv[n*n-i-n+1]%MOD;
            t = t*fac[n]%MOD*fac[n*n-n]%MOD;
            ans = (ans+t)%MOD;
        }
        cout << ans << endl;
    }
    return 0; 
}
posted @ 2021-09-05 15:18  shuitiangong  阅读(65)  评论(0编辑  收藏  举报