昨日のProblem 405に関連するが解くのには必要のない情報。
10e乗の剰余は、Pythonにはpow関数が用意されて簡単に計算できます。例えば、3の1010乗の123456789の剰余は、
pow(3, 10 ** 10, 123456789)
で求められます。しかし、指数が大きくなってくると段々厳しくなってきます。この関数は指数を計算しなければならないからです。そのため、pow(a, 10 ** e, D)はO(e1.6)くらいかかると思われます。
もうちょっとなんとかならないでしょうか。
a100 = (a10)10
となります。a10eなら10乗の計算をe回繰り返せばよいです。このためO(e)程度で計算できるはずです。動かしてみると最初は少し前者の方が速いですが、e = 106から逆転して差が広がります。
e | pow | 自作 |
---|---|---|
10^4 | 9ms | 13ms |
10^5 | 119ms | 125ms |
10^6 | 2.36s | 1.25s |
10^7 | 71.7s | 12.4s |
import time def pow10(n, e, D): for _ in xrange(e): n2 = n * n n4 = n2 * n2 n5 = n4 * n n = n5 * n5 % D return n for E in xrange(4, 8): N = 10 ** E D = 123456789 t0 = time.clock() print E, pow(3, 10 ** N, D), time.clock() - t0 t0 = time.clock() print E, pow10(3, N, D), time.clock() - t0