C 求两个非常大的数与一个非常大的数的乘积模
在一个编程练习中,我需要找出一个非常大的数的模,比如2的幂为500000(输入中的最大数),100000007作为其他计算的一部分 正如我可能不得不多次发现的那样,一种方法是创建一个500000的数组。但它会的C 求两个非常大的数与一个非常大的数的乘积模,c,algorithm,data-structures,C,Algorithm,Data Structures,在一个编程练习中,我需要找出一个非常大的数的模,比如2的幂为500000(输入中的最大数),100000007作为其他计算的一部分 正如我可能不得不多次发现的那样,一种方法是创建一个500000的数组。但它会的 阻塞了大量内存,所以我想知道有没有更好的方法来实现这一点?现在是使用内存的最佳时机。您可以按如下方式计算xy(模数模数): int repeatedSquaring(int x, int y, int modulus) { if (y == 0) return 1; in
阻塞了大量内存,所以我想知道有没有更好的方法来实现这一点?现在是使用内存的最佳时机。您可以按如下方式计算xy(模数<代码>模数代码>):
int repeatedSquaring(int x, int y, int modulus) {
if (y == 0) return 1;
int val = repeatedSquaring(x, y / 2);
val = (val * val) % modulus;
if (y % 2 == 1) {
val = (val * x) % modulus;
}
return val;
}
该算法只需要O(logy)乘法和模来计算。此外,每个中间值最多为模
2,因此如果模不太大,您可以使用plainint
s进行计算
希望这有帮助 像这样简单的事情怎么样
#include <stdio.h>
unsigned long PowMod(unsigned long p)
{
unsigned long prod;
if (p == 0)
return 1;
if (p == 1)
return 2;
prod = PowMod(p / 2);
prod = (unsigned long long)prod * prod % 1000000007ULL;
if (p % 2 != 0)
{
prod = prod * 2 % 1000000007ULL;
}
return prod;
}
int main(void)
{
printf("%lu\n", PowMod(3));
printf("%lu\n", PowMod(4));
printf("%lu\n", PowMod(30));
printf("%lu\n", PowMod(31));
printf("%lu\n", PowMod(32));
printf("%lu\n", PowMod(33));
return 0;
}
您还可以使用Euler定理减小指数的大小(不超过模数的大小)。
int
不能保证能够容纳100000007
,因为它只能保证包含16位。在long
@AlexeyFrunze中保证32个-你甚至不能保证。规范没有指定int和long的大小,只要sizeof(int)≤ sizeof(long)。@templatetypedef C指定int
as-32767到32767的最小范围至少要实现16位。对于要求至少32位的long
,也存在类似的最小范围。@chux你确定吗?你能引用一下吗?我总是觉得所有这些都是实现定义的。
8
16
73741817
147483634
294967268
589934536