我希望这不是 Project Euler 或其他类似的网站。
首先将数字1111... 命名为Repunit。
作为modular arithmetic 状态:
如果a1 = b1 mod n 和a2 = b2 mod n 那么:
a1 + a2 = b1 + b2 mod n
a1 - a2 = b1 - b2 mod n
a1 * a2 = b1 * b2 mod n
size n 的重复单位可以以 10 为底写为:1*10^n + 1*10^(n-1) ... + 1*10 + 1。
这将是1*10^n + 1*10^(n-1) ... + 1*10 + 1 = X mod n
1 = x1 mod n
x1*10 + 1 = x2 mod n
x2*10 + 1 = x3 mod n
...
x(n-1)*10 + 1 = X mod n
最后的模块化结果将是解决方案:
C++ 代码,Steve Cox 提出的更新代码:
#include <iostream>
#include <map>
#include <cmath>
long long repunit_module(long long repunit_size, long long n) {
if (repunit_size < 100) {
// Calculate normally
long long module_value = 1;
for (long long i = 2; i <= repunit_size; i++) {
module_value = (module_value * 10 + 1) % n;
}
return module_value;
} else {
// x(2n) = (x(n+1) - x(n) + 1) * x(n)
long long xn = repunit_module(repunit_size / 2, n); // x(n) mod n
long long xn1 = (xn * 10 + 1) % n; // x(n+1) mod n
long long rest = xn1 - xn + 1;
if (rest < 0) // normalyze for module
rest += n;
long long result = ((rest % n) * xn) % n;
if (repunit_size % 2 == 1) { // if size is 2n + 1 calc the last
return (result * 10 + 1) % n;
} else { // if size is
return result;
}
}
}
int main() {
long long rps = std::pow(10, 16);
std::cout << repunit_module(3, 3) << std::endl;
std::cout << repunit_module(4, 7) << std::endl;
std::cout << repunit_module(5, 18) << std::endl;
std::cout << repunit_module(rps, 123456789) << std::endl;
}