분할정복 거듭제곱

밑을 반복해서 곱하는 대신 지수를 절반씩 줄여가며 a^n을 O(log n)에 계산하는 분할 정복 기법입니다.

동작 과정

예시: 3^13 계산하기. half = pow(base, exp/2)로 지수를 절반으로 나눈 뒤, 짝수면 half*half, 홀수면 base*half*half로 결합한다.

divide: 지수를 절반으로 줄여가며 내려간다
pow(3, 13)  13은 홀수 → half 필요: pow(3, 6)
  pow(3, 6)   6은 짝수 → half 필요: pow(3, 3)
    pow(3, 3)   3은 홀수 → half 필요: pow(3, 1)
      pow(3, 1)   1은 홀수 → half 필요: pow(3, 0)
        pow(3, 0)   base case → 1

combine: 아래에서 위로 올라오며 결합한다
pow(3, 0) = 1
pow(3, 1) = base * half * half = 3 * 1 * 1 = 3        (홀수)
pow(3, 3) = base * half * half = 3 * 3 * 3 = 27        (홀수)
pow(3, 6) = half * half = 27 * 27 = 729                (짝수)
pow(3, 13) = base * half * half = 3 * 729 * 729 = 1594323  (홀수)

지수가 13 → 6 → 3 → 1 → 0으로 매번 절반씩 줄어들기 때문에, 1부터 반복 곱셈하는 O(n) 방식과 달리 재귀 호출이 log₂(n) 단계만에 끝난다.

구현

long power(long base, long exp) {
    if (exp == 0) {
        return 1;
    }
    long half = power(base, exp / 2);
    if (exp % 2 == 0) {
        return half * half;
    }
    return base * half * half;
}

복잡도

지수를 매 호출마다 절반으로 나누므로 재귀 깊이는 log₂(n)이다.

단순히 base를 exp번 반복해서 곱하는 방식은 O(n)이므로, 지수가 커질수록 분할정복 방식의 이득이 커진다.

주의사항

핵심 정리

→ 분할 정복

CSLOG에서 보기