C 计算n!m不是素数时的mod m
我读过很多计算n的好算法!mod m,但当m为素数时,它们通常有效。我想知道当m不是素数时是否存在一些好的算法。如果有人也能编写算法的基本函数,我会很有帮助。我一直在使用C 计算n!m不是素数时的mod m,c,algorithm,math,modulus,C,Algorithm,Math,Modulus,我读过很多计算n的好算法!mod m,但当m为素数时,它们通常有效。我想知道当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 = (
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;
}
long-long-factMOD(long-long n,long-long-mod)
{
长res=1;
而(n>0)
{
对于(长i=2,m=n%mod;i 0)
res=mod-res;
}
返回res;
}
但当我试图打印factMOD(4,3)时,得到了错误的答案。此算法的来源是:基本算法对
m的任何值都有效:
product := 1
for i := 2 to n
product := (product * i) mod m
return product
一个简单的优化是,只要product
变为0,就可以提前退出并返回0。如果n>m,您也可以在开始时返回0,因为这保证了n!是m的倍数。基本算法对m的任何值都有效:
product := 1
for i := 2 to n
product := (product * i) mod m
return product
一个简单的优化是,只要product
变为0,就可以提前退出并返回0。如果n>m,您也可以在开始时返回0,因为这保证了n!是m的倍数。这就是我得出的结论:
#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;
}
在几分之一秒内运行。这就是我想到的:
#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;
}
在几分之一秒内运行。只需执行mod m的所有乘法运算-这不会很困难。-当乘法结果大于m
时,取模m
@mvp-n,数量级为10^7。我需要一个更好的算法来实现。你考虑过使用链式模的算法吗<代码>(a*b)mod p=((a mod p)*(b mod p))mod p
。这可以很好地帮助你解决你的问题,特别是当你遇到零的时候,提前退出捷径。@WhozCraig这实际上已经尽可能多地做到了;只是有点含蓄。乘法的左侧是正在运行的乘积,它已经是mod-m了;如果你应用任何一个早期的退出优化,乘法的右边应该已经小于m,这意味着取mod m是不可行的。只需执行mod m的所有乘法-这不会很困难。-当乘法结果大于m
时,取模m
@mvp-n,数量级为10^7。我需要一个更好的算法来实现。你考虑过使用链式模的算法吗<代码>(a*b)mod p=((a mod p)*(b mod p))mod p
。这可以很好地帮助你解决你的问题,特别是当你遇到零的时候,提前退出捷径。@WhozCraig这实际上已经尽可能多地做到了;只是有点含蓄。乘法的左侧是正在运行的乘积,它已经是mod-m了;如果你应用任何一个早期的退出优化,乘法的右边应该已经小于m,这意味着取mod m是不可行的。这个算法不足以解决我的问题。我被赋予了接近10^7的n。这将大大超过时间限制。@kavish:你试过实现它吗?对于我来说,Python是一种速度相对较慢的语言,它几乎可以立即运行。@kavish 10^7不是一个很大的数字。@kavish您尝试过这个算法来检查它是否满足您的时间限制吗?@kavish看到我的答案了吗。我已经实现了几乎完全相同的算法(没有霍布斯提出的优化),但它立即为我运行n=1000000
…这个算法不足以解决我的问题。我被赋予了接近10^7的n。这将大大超过时间限制。@kavish:你试过实现它吗?对于我来说,Python是一种速度相对较慢的语言,它几乎可以立即运行。@kavish 10^7不是一个很大的数字。@kavish您尝试过这个算法来检查它是否满足您的时间限制吗?@kavish看到我的答案了吗。我已经实现了几乎完全相同的算法(没有霍布斯提出的优化),但它在n=1000000
..@Blender中立即运行,非常…:-(遗憾的是,他太固执了……但你知道,我必须提高自己的声誉,因为我没有太多的时间,所以,我会有一个忙碌的星期……@Blender:不,实际上这不是我的家庭作业。我在网上遇到了一些很好的组合问题,我被困在其中一类问题中。@kavish,我的答案有什么问题吗,最后我的答案是ma你不接受吗?@kavish,这与任何其他建议有什么不同?@H2CO3:你的回答我接受了。我只是站在这个方法的反面,因为我认为,如果有这么多好的m prime算法,那么也会有好的m not prime算法。@Blender…:-(遗憾的是,他太固执了……但你知道,我必须提高自己的声誉,因为我没有太多的时间,所以,我会有一个忙碌的星期……@Blender:不,实际上这不是我的家庭作业。我在网上遇到了一些很好的组合问题,我被困在其中一类问题中。@kavish,我的答案有什么问题吗,最后我的答案是ma你不接受吗?@kavish,这与任何其他建议有什么不同?@H2CO3:你的回答我接受了。我只是站在这个方法的反面,因为我认为如果有这么多好的m prime算法,那么m not prime也会有好的算法。