与えられる数がとても大きい可能性があるため、計算時間を短縮するのが重要です。バイナリ累乗法 (Binary Exponentiation) は、大きなべき乗を効率的に計算できるアルゴリズムです。通常の方法(1から n までループして、そのたびに x を乗じる)よりも、乗算回数をかなり減らせるので高速に計算できます。
def binpow(x, n, m):
if n == 0: # 基本ケース: x^0 = 1
return 1
if n % 2 == 0: # nが偶数の場合 => halfを計算して掛け合わせる
half = binpow(x, n // 2, m) # halfを計算する
return (half * half) % m # res = x^(n/2) * x^(n/2)
# nが奇数の場合 => res = x * x^(n-1)
return (x * binpow(x, n - 1, m)) % m
バイナリ累乗法を使うことで、n を毎回2で割っていけるため、計算量は から へと大きく削減されます。n が奇数のときは一度乗算を行いますが、その後の再帰呼び出しでは n が偶数になるので、結果的に効率的な計算が可能です。