1 분 소요



https://www.acmicpc.net/problem/1629



📌 문제

문제 유형

  • 수학
  • 분할정복


📘 문제 설명



🔍 문제 풀이

문제 해결 절차

지수 B가 크므로 반복문으로 A를 B번 곱하면 시간 초과 발생 -> 따라서 분할 정복을 사용해 ` O(log B)`로 계산해야 한다.

a=2, b=10이라고 가정해보자.

제곱은 다음과 같이 분할이 가능하다.


이렇게 재귀함수로 b가 0이 될 때까지 절반으로 계속 나눠서 아래 공식을 적용하면 된다.

  • b가 짝수일 때 : half * half
  • b가 홀수일 때 : half * half * a

재귀 호출의 깊이만큼 if (b % 2 == 0) 분기가 호출되고,
올라오면서 half * half 또는 half * half * a 식으로 곱셈이 누적된다.


재귀 호출 도중마다 C로 나머지 연산을 수행해 오버플로우를 방지할 수 있다.

예시

pow(2, 4, 13)
 half = pow(2, 2, 13)
→→ half = pow(2, 1, 13)
→→→ half = pow(2, 0, 13)  return 1
→→ return (1 * 1 * 2) % 13 = 2
 return (2 * 2) % 13 = 4



💻 전체 코드

a를 b번 곱해야 하는데, 결국 a를 b번 곱한 결과를 간접적으로 만들어낸다.

import java.io.*;
import java.util.*;

public class Main {
    public static void main (String[]args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        StringTokenizer st = new StringTokenizer(br.readLine());
        int a = Integer.parseInt(st.nextToken());
        int b = Integer.parseInt(st.nextToken());
        int c = Integer.parseInt(st.nextToken());

        System.out.println(pow(a,b,c));
    }

    public static long pow(long a, long b, long mod){
        if(b==0) return 1;

        long half = pow(a, b / 2, mod);
        if (b % 2 == 0) return half * half % mod; //  a^(b/2) * a^(b/2) = a^b
        else return (half * half % mod) * a % mod;
    }
}


카테고리:

업데이트:

댓글남기기