【问题标题】:Calculating n! mod m when m is not prime计算 n!当 m 不是素数时 mod m
【发布时间】:2013-02-10 21:03:43
【问题描述】:

我已经阅读了很多很好的算法来计算 n! mod m 但它们通常在 m 为 prime 时有效。我想知道当 m 不是素数时是否存在一些好的算法。如果有人也可以编写算法的基本功能,我会有所帮助。我一直在使用

long long factMOD(long long n,long long mod)
{
    long long res = 1; 
    while (n > 0)
    {
        for (long long i=2, m=n%mod; i<=m; i++)
        res = (res * i) % mod;
        if ((n/=mod)%2 > 0) 
        res = mod - res;
    }
    return res;
}

但是当我尝试打印 factMOD(4,3) 时得到错误的答案。这个算法的来源是:
http://comeoncodeon.wordpress.com/category/algorithm/

【问题讨论】:

  • 只做所有的乘法 mod m - 这不会很困难。
  • This - 只要乘法的结果大于m,就取模m
  • @mvp-n 给了我 10^7 的顺序。我需要一个更好的算法来做到这一点。
  • 您是否考虑过利用链式模数的算法? (a*b) mod p = ((a mod p) * (b mod p)) mod p。这可以很好地帮助您解决问题,尤其是在与任何遇到零时的提前退出捷径相结合时。
  • @WhozCraig 这实际上已经尽可能地完成了;这只是一种隐含的。乘法左边是运行积,已经是mod-m;如果您应用任何一种提前退出优化,乘法的右侧应该已经小于 m,这意味着取它 mod m 是无操作的。

标签: c algorithm math modulus


【解决方案1】:

基本算法对m的任意值都有效:

product := 1
for i := 2 to n
    product := (product * i) mod m
return product

并且一个简单的优化是你可以提前退出并在product 变为 0 时返回 0。如果 n > m,你也可以在开头返回 0,因为这保证了 n!是 m 的倍数。

【讨论】:

  • 这个算法不足以解决我的问题。我得到的 n 接近 10^7。这将大大超出时间限制。
  • @kavish:你试过实现它吗?它在 Python 中几乎可以立即运行,这是一种相对较慢的语言。
  • @kavish 10^7 不是一个很大的数字。
  • @kavish 您是否尝试过此算法来检查它是否满足您的时间限制?
  • @kavish 查看我的回答。我已经实现了几乎完全相同的算法(没有 Hobbs 建议的优化),但它为我立即运行n = 1 000 000...
【解决方案2】:

这是我想出的:

#include <stdio.h>
#include <stdlib.h>

unsigned long long nfactmod(unsigned long long n, unsigned long long m)
{
    unsigned long long i, f;
    for (i = 1, f = 1; i <= n; i++) {
        f *= i;
        if (f > m) {
            f %= m;
        }
    }
    return f;
}

int main(int argc, char *argv[])
{
    unsigned long long n = strtoull(argv[1], NULL, 10);
    unsigned long long m = strtoull(argv[2], NULL, 10);

    printf("%llu\n", nfactmod(n, m));

    return 0;
}

还有这个:

h2co3-macbook:~ h2co3$ ./mod 1000000 1001001779
744950559
h2co3-macbook:~ h2co3$

在几分之一秒内运行。

【讨论】:

  • @Blender 相当... :-( 可悲的是他太固执了...但是你知道,我必须积累声誉,因为我没有太多时间了,我会有忙碌的一周……
  • @Blender:不,实际上这不是我的作业。我正在处理一些在线很好的组合问题,但我被困在其中一种类型中。
  • @kavish 我的回答到底有什么问题让你不接受?
  • @kavish 这与其他任何建议有何不同?
  • @H2CO3:你的回答我已经接受了。我只是对这种方法持消极态度,因为我认为如果 m prime 有这么多好的算法,那么 m not prime 也会有好的算法。
猜你喜欢
  • 2012-04-01
  • 1970-01-01
  • 2011-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-18
  • 2015-12-19
  • 1970-01-01
相关资源
最近更新 更多