명제 : (A * B)%N = ((A%N) * (B%N)) % N
증명:
(A * B) % N = ((q1 * N + r1) * (q2 * N + r2)) % N
= (q1 * N * q2 * N + q1 * N * r2 + q2 * N * r1 + r1 * r2) % N
여기서 중요한 점은, N의 배수는 %N을 취하면 항상 0이 된다는 것입니다:
따라서, 위의 식은 다음과 같이 단순화됩니다:
(A * B) % N = (r1 * r2) % N
((A % N) * (B % N)) % N
((A % N) * (B % N)) % N = (r1 * r2) % N
(A \times B) \% N = ((A \% N) \times (B \% N)) \% N
분할 정복(Divide and Conquer)은 문제를 작은 부분 문제로 나누어 해결하고, 부분 문제의 해를 결합하여 원래 문제의 해를 구하는 전략입니다. 이 알고리즘은 문제를 재귀적으로 해결하는 데 자주 사용됩니다.
분할 정복의 3단계
분할 정복 알고리즘은 큰 문제를 작은 문제로 나누어 해결하는 효율적인 접근법입니다. 다양한 알고리즘에 적용되며, 재귀를 통한 문제 해결에서 자주 사용됩니다.

package BOJ;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Boj1629 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
int a = Integer.parseInt(input[0]);
int b = Integer.parseInt(input[1]);
int c = Integer.parseInt(input[2]);
long answer = modularExponentiation(a, b, c);
System.out.println(answer);
}
// 분할 정복을 이용한 거듭제곱
private static long modularExponentiation(long base, long exp, long mod) {
if (exp == 0) {
return 1; // A^0 = 1
}
// A^(B/2) // 분할 단계
long half = modularExponentiation(base, exp / 2, mod);
half = (half * half) % mod; // 정복 및 결합
// B가 홀수일 경우 추가로 base를 곱해준다.
if (exp % 2 != 0) {
half = (half * base) % mod; // 홀 수 처리
}
return half;
}
}
분할 정복을 이용한 거듭제곱:
이 알고리즘이 분할 정복인 이유는, 문제를 절반으로 분할하여 재귀적으로 해결하고, 부분 문제를 결합하여 원래 문제를 해결하기 때문입니다. 이를 통해 효율적으로 큰 지수를 다룰 수 있게 됩니다.