模量的重复循环
Repeating Cycle of Modulus
本文关键字:循环 更新时间:2023-10-16
有没有一种有效的方法来找到1111..nmod M的值
人们总是可以使用重复平方来找到
10modM+101modm+102modM+103ModM+。。。10n模式M
有比这更快的方法吗?
您可以使用一种几乎类似于平方求幂的算法来解决此问题。
首先,如果你有一个偶数的1,你可以看到:
11111111 = 1111 * 10001
n ones n/2 ones (10^(n/2) + 1)
这使1的数量增加了一倍。此外,
1111111 = 111111 * 10 + 1
n ones n-1 ones
将这些观测结果形式化,并为方便起见,将n个1 111…1的数字命名为J(n):
- 如果n是偶数,则J(n)=(10^(n/2)+1)J(n/2
- 如果n是奇数,则J(n)=10*J(n-1)+1
您可以使用这些递归(加上通过平方计算10^(n/2)的幂的实际实现)模M来计算O(log(n)^2)时间内的结果。
下面是一些实现这一点的C代码。如果你想要一个大的M
(你需要M^2来适应你的类型),你必须使用比int
更长的类型,以避免溢出。
#include <stdio.h>
// Computes a to the power of n modulo m.
int pow_mod_m(int a, int n, int m) {
if (n == 0) { return 1; }
if (n == 1) { return a; }
if (n % 2 == 0) {
int k = pow_mod_m(a, n/2, m);
return (k * k) % m;
}
return (pow_mod_m(a, n-1, m) * a) % m;
}
// Computes J(n) modulo m
int j_mod_m(int n, int m) {
if (n == 1) {
return 1;
}
if (n % 2 == 0) {
return (j_mod_m(n/2, m) * (1 + pow_mod_m(10, n/2, m))) % m;
}
return (j_mod_m(n-1, m) * 10 + 1) % m;
}
int main(int argc, char**argv) {
for (int i = 1; i < 1000; i++) {
printf("%d: %dn", i, j_mod_m(i, 12345));
}
return 0;
}
如果10是幂零的(如果M=2^a*5^b),或者在某个点开始循环,则10的幂最终将达到0。(实际上0,0,0…也是一个循环。)循环的长度可以大到M-1。因此,计算幂,直到观察到重复值,并使用简单代数根据观察到的不同幂来收集项。
我相信这将复杂性从O(n)降低到O(M),这显然是对大型n的改进。
相关文章:
- 如何循环打印顶点结构
- 如何在C++中从两个单独的for循环中添加两个数组
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 正在尝试了解输入验证循环
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 循环后如何继续阅读
- Ardunio UNO解决了多个重叠的定时器循环
- Eigen如何在容器循环中干净地附加矩阵
- 在某些循环内使用vector.push_back时出现分段错误
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 为什么我的for循环不能正确获取argv
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- while循环中while循环的时间复杂度是多少
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 为什么在这个代码结束循环中没有得到结束
- 在基于范围的for循环中使用结构化绑定声明
- 用于C++中带有数组和指针的循环
- 循环中的随机函数
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 在循环C++中指定字符串之后,不会打印该字符串