组合数II
886. 求组合数 II
题目
给定 n
组询问,每组询问给定两个整数 a
,b
,请你输出 $C_b^amod(10^9+7)$ 的值。
输入格式
第一行包含整数 n
。接下来 n
行,每行包含一组 a
和 b
。
输出格式共 n
行,每行输出一个询问的解。
数据范围 $1≤n≤10000$,$1≤b≤a≤105$
输入样例:
1 | 3 |
输出样例:
1 | 3 |
题解
Q1:明明是除法为什么要特意转换成乘法
那是因为这道题目最后是要求余的,模运算与基本四则运算有些相似,但是除法例外。其规则如下:
(a + b) % p = (a % p + b % p) % p
(a - b) % p = (a % p - b % p) % p
(a _ b) % p = (a % p _ b % p) % p
但对于除法却不成立,即(a / b) % p 不等于 (a % p / b % p) % p 。
Q2:那么为什么非要转换成乘法逆元呢?
不能使用除法,显然数学家们是不能忍受这种局面的,他们扔出了“逆元”来解决这个问题。
证明:
1 | 开始a/b≡m(modp) -------① |
Q3 所以逆元要怎么求呢?(k!)(−1)≡(k - 1)!(-1)^(p−2)是哪里来的? (-1)是逆元!!
这里其实是有个小技巧的,因为 mod 是 1e9 +7,其实是一个非常大的质数,我们知道质数的因子只有 1 和其本身,所以 2~1e9 + 6 其实都是与 1e9 + 7 是互质
根据在 快速幂求逆元
我们知道若整数 b,m 互质,并且对于任意的整数 a,如果满足 b|a,则存在一个整数 x,使得 a/b≡ax(modm),则称 x 为 b 的模 m 乘法逆元,记为 $b^{−1}(modm)$。
b 存在乘法逆元的充要条件是 b 与模数 m 互质。当模数 m 为质数时,$b^{(m−2)}$ 即为 b 的乘法逆元。
以为 2~1e9 + 6 其实都是与 1e9 + 7 是互质的,所以根据小费马定理可以换算出$b^{(m−2)}$ 即为 b 的乘法逆元。
1 | 费马小定理:若 p 是质数,整数b不是p的倍数,则 b^(p−1)≡1(modp). |
Q4:为什么在求逆元的时候 mod 后还要 mod
其实这可以参照模运算的乘法法则
因为在乘法过程中,答案会非常大,而 mod 多一次并不会改变最终的答案,可以举个小一点的例子,我太懒了,这里就不举了只是在过程中把量减小了,不会在计算过程中超出数据范围而出现什么奇怪的答案
代码
1 | #include<iostream> |