본문 바로가기

분할 정복을 이용한 거듭제곱/정수 거듭제곱

백준 13171번: A

www.acmicpc.net/problem/13171

 

13171번: A

음이 아닌 두 정수 A, X 가 있을 때 AX을 구하는 방법을 생각해보자. 물론 이 수는 매우 클 수 있기에, 1,000,000,007 (= 109 + 7)로 나눈 나머지를 구할 것이다. a mod x를 a를 x로 나눴을 때의 나머지라고 표

www.acmicpc.net


본문에 Binary Exponentiation의 원리가 잘 설명되어있습니다.

 

$A^{X} \left ( mod \left ( 10^{9} + 7 \right ) \right )$ 을 잘 구해주면 됩니다.

 

다음 링크에 있는 함수만 사용하였습니다.

 

2021/01/23 - [분할 정복을 이용한 거듭제곱] - 기본 이론

 

기본 이론

큰 자연수 A, B, C에 대해 $ A^{B}\left ( mod M \right ) $의 값을 구하는 문제가 많습니다. 이 카테고리에서는 이런 문제를 몇 가지 풀어보려고 합니다. 이 글에서는 문제를 풀기 이전에 주요 개념을 간략

memoacmicpc.tistory.com

 

이때 $10^{9}+7$ 의 크기가 long long의 범위에 비해 상당히 작기 때문에, add_modular 함수는 굳이 사용하지 않았습니다.

 

#include <stdio.h>

long long multiply_modular (long long a, long long b, long long M);
long long power_modular (long long a, long long b, long long M);

int main() {
	long long A, X;
	scanf("%lld", &A);
	scanf("%lld", &X);
	printf("%lld", power_modular(A, X, 1000000007));
	return 0;
}

long long multiply_modular (long long a, long long b, long long M) {
	a %= M;
	b %= M;
	long long result = 0;
	while (b > 0) {
		if (b & 1) {
			result = (result + a) % M;
		}
		a = (a << 1) % M;
		b >>= 1;
	}
	return result;
}

long long power_modular (long long a, long long b, long long M) {
	a %= M;
	long long result = 1;
	while (b > 0) {
		if (b & 1) {
			result = multiply_modular (result, a, M);
		}
		a = multiply_modular (a, a, M);
		b >>= 1;
	}
	return result;
}

 

C11 코드이고, 1116KB, 0ms가 나왔습니다. (번호 25562824)


백준에 있는 Binary Exponentiation을 이용하는 문제 중 가장 쉬운 편에 속하는 문제 같습니다.

 

본문에 설명이 잘 되어 있으나 처음 보는 사람한테는 생각하기 어려울 것 같습니다.