如何计算F(n)%mod
,其中mod
是素数。
和F(n)=n!/(q!^r)%mod
....(x^r
代表pow(x,r)
)。
我正在尝试使用fermat的小定理来计算逆模,但我遇到的问题是fermat仅适用于gcd(denominator,mod)=1
。
还有其他方法可以解决这个问题。
答案 0 :(得分:1)
如果模数是素数,则可以使用扩展的欧几里德算法计算逆:
function inverse(x, m)
a, b, u = 0, m, 1
while x > 0
q = b // x # integer division
x, a, b, u = b % x, u, x, a - q * u
if b == 1 return a % m
error "must be coprime"
如果模数是复合的,只要 x 和 m 是互质的,该算法仍然可以工作。如果他们共享一个因子,则反向不存在。
答案 1 :(得分:1)
如果gcd不是,则没有模块化反转 1.位于Wikipedia page顶部:
当且仅当a和m是互质时(即,如果gcd(a,m)= 1),模m的乘法逆存在。
答案 2 :(得分:0)
当你试图计算这个商模 p (对于某个素数)时,让我假设你知道结果是一个整数。
正如人们所提到的,如果 q> = p ,那么你就无法计算分母的倒数,因为 q!与模数不相符,所以这个数字是不可逆的。但这并不意味着你无法计算整个商模 p 。
让 a , b 分别是分子和分母中 p 因子的数量。结果是整数,我们有 a> = b 。如果不等式是严格的,则结果为0.否则,如果等式成立,我们可以从分子和分母中移除这些因子并继续,因为现在分母与 p 相互作用。
因此,让我先从有效计算 a , b 数字的方法开始。密钥称为De Polignac's formula,它表示对于给定的 k , k!中的 p 因子的数量可以按这样计算:
int polignac(int k, int p) {
int res = 0, power = p;
while (k >= power) {
res += k/power;
power *= p;
}
return res;
}
因此,我们获得 n!和 q!的 p 因子,因此获得是微不足道的p 因子 q!^ r (只需乘以 r )。
在严格的不平等情况下,我们已经完成了。如果没有,我们必须计算分子和分母的模数“丢弃”所有 p 因子。这也可以有效地解决。我们可以像这样写 k!:
ķ! = 1 x 2 x 3 x ... x p x(p + 1)x(p + 2)... x(p ^ 2)x ...
如果我们删除 p 因子并应用modulo,我们会有以下内容:
ķ! = 1 x 2 x 3 x ... x (这里没有,只有1) x 1 x 2 ... x (另一个1) x ... < / em>的
因此,同一产品不断重复直至结束。因此,计算 1 x 2 x ... x(p - 1) modulo p ,将其提升到适当的功率模 p (使用快速指数)只是乘以“reamaining”项,因为一般 k 不能被 p 整除。