Is there a efficient method to find the value of 1111..nmod M?
One can always use repeated squaring to find
100mod M + 101mod M + 102mod M + 103mod M + ...10nmod M
Is there any faster method than this?

- 221
- 3
- 12
-
Euler's Totient function puts an upper bound on how long the cycle can be. So you could run that to give you an idea on whether it's even worth it to find the cycle in the first place. – Mysticial Feb 28 '15 at 01:57
2 Answers
You can solve this using an algorithm almost like exponentiation by squaring.
First, if you have an even number of 1s, you can see that:
11111111 = 1111 * 10001
n ones n/2 ones (10^(n/2) + 1)
which doubles the number of ones. Also,
1111111 = 111111 * 10 + 1
n ones n-1 ones
Formalising these observations, and for convenience naming the number with n ones 111...1 as J(n):
- If n is even, J(n) = (10^(n/2) + 1)J(n/2).
- If n is odd, J(n) = 10*J(n-1) + 1.
You can use these recurrences (plus an actual implementation of exponentiation by squaring to compute 10^(n/2)) modulo M to compute the result in O(log(n)^2) time.
Here's some C code that implements this. You'll have to use a longer type than int
do avoid overflow if you want a large M
(you need M^2 to fit into your type).
#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: %d\n", i, j_mod_m(i, 12345));
}
return 0;
}

- 54,811
- 11
- 92
- 118
-
shouldn't `if (n == 1) { return a; }` be `if (n == 1) { return a mod m; }` in `pow_mod_m`? – Zaid Khan Mar 21 '19 at 09:42
-
@Bateman yes, that'd be better. I don't think the code as written produces wrong results unless there's an overflow, but with your version of the code, the range of values that produce an overflow is smaller. – Paul Hankin Mar 21 '19 at 13:57
The powers of 10 will eventually hit 0 if 10 is nilpotent (if M = 2^a * 5^b), or start cycling at some point. (Actually 0,0,0... is also a cycle.) The length of the cycle can be as large as M-1. Therefore compute powers until repeat values are observed, and use simple algebra to collect the terms in terms of the distinct powers observed.
I believe this knocks the complexity down from O(n) to O(M), which is obviously an improvement for large n.

- 59,258
- 35
- 162
- 290
-
-
@user3318603 short answer, not really. This is one of those problems that modern cryptography relies on being unsolvable. – djechlin Feb 28 '15 at 05:12