第十四届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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值