逆模的问题,其中gcd(分母,mod)!= 1

时间:2014-11-11 23:35:49

标签: java c algorithm math data-structures

如何计算F(n)%mod,其中mod是素数。 和F(n)=n!/(q!^r)%mod ....(x^r代表pow(x,r))。

我正在尝试使用fermat的小定理来计算逆模,但我遇到的问题是fermat仅适用于gcd(denominator,mod)=1

还有其他方法可以解决这个问题。

3 个答案:

答案 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 整除。