第十四屆HNCCP湖南省賽 B 2018 組合數學+逆元 csuoj 2164

題目鏈接:CSU-ACM 2164

2018

Description

Bobo 想統計滿足下麪條件的矩陣 A 的數量。

矩陣 A 有 n 行 m 列,每個元素都是正整數。第 i 行第 j 列的元素用 Ai, j 表示。
A1, 1 = 2018.
對於所有 2 ≤ i ≤ n, 1 ≤ j ≤ m,Ai, j 是 Ai − 1, j 的約數。
對於所有 1 ≤ i ≤ n, 2 ≤ j ≤ m,Ai, j 是 Ai, j − 1 的約數。
因爲滿足條件的矩陣 A 數量很多,Bobo 只想統計滿足條件的矩陣數量除以 (10e9 + 7) 的餘數。

1 ≤ n, m ≤ 2000
數據組數不超過 10e5.

Input

輸入文件包含多組數據,請處理到文件結束。

每組數據包含 2 個整數 n 和 m.

Output

對於每組數據輸出 1 個整數表示所求的數量除以 (109 + 7) 的餘數。

Sample Input

1 1
1 2
2 2
2 3
2000 2000

Sample Output

1
4
25
81
570806941

Hint

對於第二組樣例(n = 1, m = 2),滿足條件的矩陣 A 有 (2018, 2018),(2018, 1009),(2018, 2),(2018, 1) 共 4 種。

Source

2018湖南省第14屆大學生計算機程序設計競賽

Author

ftiasch

題解:不知道別人打表幹嘛,顯然是組合數學規律,組合數的底數是n+m,上面的數隨便取n或者m就行。詳見AC代碼

// 組合數
#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int maxn = 4005;  ///
const int M = 1000000007;

LL fac[maxn + 1] = {1, 1}, inv[maxn + 1] = {1, 1}, f[maxn + 1] = {1, 1};

LL
C(LL a, LL b) {
    return (fac[a] * inv[b] % M * inv[a - b] % M) % M;
}

void
init() {
    for(int i = 2; i < maxn; i++) {
        fac[i] = fac[i - 1] * i % M;
        f[i] = (M - M / i) * f[M % i] % M;
        inv[i] = inv[i - 1] * f[i] % M;
    }
}

int
main() {
    int n, m;

    init();
    while( ~scanf("%d %d", &n, &m) ) {
        LL ans = ((C(n + m, n) - 1 + M) % M * (C(n + m, n) - 1 + M ) % M) % M;

        printf("%lld\n", ans);
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章