빠른 전원 모듈
즉, 모드 (C)의 값을 빠르게 (A ^ B)을 얻었다. 매우 큰 B (A)의 값을 직접 오버플 비효율적 발생할 수 ^ B 찾으면 때문에.
생각
원리에 기초 \ (A * B 형 \의 %의 C = ((A \ %의 C) * (B의 \의 %의 C)) \ % C \) , \ (A ^ B의 \의 %의 C = (A \의 %의 C) ^ B \ % C 형 \) 식.
빠른 전력 해결 :
B의 이진 표현 인덱스에 \ (b = (. 1-N-B_n B_ {...} b_2b_1b_0) _2 \) ,
\ (b + = b_0 B_1 * ^ 2 + 1 B_2 * 2 ^ 2 + ... + B_ {N-1} * 2 ^ {N-1} + b_n ^ 2 * N 개의 \) ,
\ (A ^ B = A ^ {b_0 B_1 * 2 ^ 1 개 + B_2 * 2 ^ 2 + ... + B_가 {N-1} * 2 ^ {N-1} +가 b_n * 2 ^ n은} = A {} ^ (B0) *는 {B_1 ^ * 2 ^ (1)} ^ {*는 B_2 * 2 ^ 2} * ... *는 B_ {^ {N-1} * 2 ^ {N-1}} *는 ^ {b_n ^ 2 * N} \) ,
\ (A ^ B의 \ %의 C = A ^ {(B0)} *는 ^ {B_1 * 2 ^ 1} *는 ^ {B_2 * 2 ^ 2} * ... *는 ^ {B_ {N-1} * 2 ^ {N-1}} *는 {b_n ^ * 2 ^ N} \ % C 형 \) ,
세트 (\ K_n가 = (A ^ {B_n * 2 ^ N-}) \ % C \) , KN 단어를 찾고, BN = 0 때 한국인 =. 1, BN =. 1 \ (KN = (A ^ {2 ^ N- }) \ % C \) , 산출 한 후 고려 \ ((A ^ ^ {N-2}) \ % C \) .
\ ((a ^ {2 ^ N}) \ % C = (A ^ {2 ^ {N-1}} \ %의 C) * (a ^ {2 ^ {N-1}} \ %의 C)] \ % C 형 \) 따라서 재귀.
코드
파이썬
def quick_powmod(a, b, c):
a = a % c
ans = 1 # 存放结果
while b != 0:
if b & 1: # 二进制与
ans = (ans * a) % c
a = (a * a) % c # 取模是防止溢出
b >>= 1 # 二进制向右移动一位
return ans
예를 들어, A는 = 2, B = 10, C = 3, (B)는 1010의 이진 표현이다.
\ (^ 2 ^ {10} = {2 * 0+. 1. 1 + 0 * 2 ^ 2 ^ 2 + 2 ^. * 3 1} \) , B는 오른쪽에서 왼쪽으로 취해진 비트, 0, 곱셈 A, 결과는 피곤 ANS 년 걸릴 곱, 1입니다.
신속한 승산 모듈
이진 가산기를 사용하여 곱셈을 변환합니다.
생각
진 승수 계산으로 전환 빠른 모듈로 지수 등.
예를 들어, \ (20 * 20 * 14 = (1110) 2 * 2 ^ 20 = 0 * 0 * 2 ^ 20 + 1 + 20 * 1 * 1 * 2 ^ 2 + 2 ^ 20 * 3 * 1 \)
코드
파이썬
def quick_mulmod(a, b, c):
ans = 0
a = a % c
while b != 0:
if b & 1 :
ans = (ans + a) % c
a = (2*a) % c
b >>= 1
return ans
예를 이해하기 위해 다시 유도를 위해 언뜻보기에 매우 어려운 정지는 이해합니다.