所以,我有一个问题。
输入包含两个数字N
和M
。 N
基本上告诉我们1
将出现的数量,M
是数字,我们用它来分割并返回余数。
1≤N≤10^16
2≤M≤10^9
Sample input:
3 3
4 7
5 18
Sample output:
0
5
5
说明:
111 % 3 = 0
1111 % 7 = 5
11111%18 = 5
时间限制:最多1秒
由于输入非常大,我显然不能使用模运算符。我在考虑按位运算符,但这也不会让我接受时间限制。有任何想法吗?谢谢!
答案 0 :(得分:1)
我希望这不是Project Euler或其他类似的网站。
首先,数字1111...
被命名为Repunit
。
如果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
的Repunits可以在基数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;
}
答案 1 :(得分:0)
好吧NetVipeC的回答变得非常难看
这个答案基于三个身份
x(1) = 1
x(n) = x(n-1) * 10 + 1
x(2n) = x(n)*(x(n)*9 + 2)
这些也支持Z_M。
我自下而上地写下了这些身份,但实现是自上而下的,因为它简单得多。
#include <stdio.h>
long long modulo(long long n, long long m) {
if (n == 1) return 1;
long long mod = modulo(n / 2, m);
long long whole = ((mod * 9 + 2) * mod) % m;
if(n & 1)
return (whole * 10 + 1) % m;
return whole;
}
int main() {
printf("%ld\n", modulo(3, 3));
printf("%ld\n", modulo(4, 7));
printf("%ld\n", modulo(5, 18));
printf("%ld\n", modulo(1e6, 123456789));
printf("%ld\n", modulo(1e15, 123456789));
}
输出:
time ./tst
0
5
5
1239742
93889873
./tst 0.00s user 0.00s system 56% cpu 0.002 total