a, b, c = map(int, input().split())
bilist = [0 for i in range(31)]
for i in range(30, -1, -1) :
bilist[i] = b // pow(2, i)
b = b - bilist[i] * pow(2, i)
powerlist = [0 for i in range(31)]
powerlist[0] = a % c
for i in range(1, 31) :
powerlist[i] = pow(powerlist[i-1], 2) % c
remain = 1
for i in range(31) :
if bilist[i] == 1 :
remain = (remain * powerlist[i]) % c
print(remain)
|
2^32 이하의 모든 자연수는 32자리 2진수로 표현된다. 즉, 2^i들의 합으로 표현할 수 있다.
그렇다면 a^b는 a^(2^i)들의 곱으로 표현할 수 있다.
b를 2진수 list bilist 형태로 바꾼다. bilist[i]가 0이라면 x_i가 0이고, 1이라면 x_i가 1인 셈이다.
다음으로 a(2^i)의 곱을 c로 나눈 나머지를 미리 저장해둘 powerlist를 만든다.
모듈러는 곱연산이 되므로, [0]번째에 a%c를 넣고 이전 값의 제곱을 c로 나누는 식으로 연쇄적으로 값을 구한다.
a^b는 위 Product 수식의 각 원소들의 곱이므로, a^b의 나머지는 각 원소들의 나머지의 곱의 나머지이다.
미리 작성한 bilist와 powerlist를 이용하여 각 원소들의 나머지를 연쇄적으로 곱해 답을 구한다.
b를 반토막씩 줄여가며 log b번의 재귀로 답을 구하는 것과 같은 방법인 것 같다.
미리 2진수 리스트를 작성해서 1의자리부터 올라갈지, 재귀함수를 짜서 절반씩 내려갈지 방법의 차이만 있다.
'Week 01 ~ 04 : 알고리즘 문제 풀이' 카테고리의 다른 글
파이썬 백준 2261 가장 가까운 두 점 (0) | 2021.11.12 |
---|---|
파이썬 백준 10830 행렬 제곱 (0) | 2021.11.12 |
파이썬 백준 2630 색종이 만들기 (0) | 2021.11.12 |
파이썬 백준 8983 사냥꾼 (0) | 2021.11.12 |
파이썬 백준 2470 두 용액 (0) | 2021.11.11 |