a의 b승을 계산해서 c로 나눈 나머지를 구해야 하는 문제다. 어려웠다. 
검색해보니까 분할정복으로 풀어야 하는 문제다. 

분할정복으로 a의 b승 구현하기 

a제곱 b는 아래와 같이 구현할 수 있다. 
int pow(int a, int b){
 if(b == 0) return 1; 
 if(b == 1) return a;
 if(b%2 == 0) { // 짝수 승이라면, 
  int temp = pow(a, b/2);
  return temp*temp;
 }
 return pow(a, b-1); // 홀수 승이면 1승 차이.
}
 
 
pow(a, b)함수로 2의 4승을 연산하려면 pow(2, 4)다. 
 
2의 0 승인 경우, 0승은 항상 1이다.
2의 1승인 경우, 1승은 항상 2이다. 
 
여기서 중요한 건, b가 짝수인 경우다. 
2의 4승 == ( 2의 2승 * 2의 2승 )
따라서 b가 짝수라면, b/2승 결과를 구해서 temp에 저장하고, temp를 제곱하면 된다. 

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

ll a, b, c;

ll rec(ll a, ll b){
  if(b == 0) return 1;
  if(b == 1) return a % c;

  long long temp = rec(a, b/2);
  if(b%2 == 0){ // b가 짝수라면,
    return (temp * temp) % c; // b/2승을 제곱하면 된다.
  }
  else{// b가 홀수라면, 1번 더 a를 곱해준다.
    return ((temp * temp) % c) * a % c;
  }
}

int main(void){
  ios::sync_with_stdio(0);
  cin.tie(0);

  cin >> a >> b >> c;
  cout << rec(a, b);
  return 0;
}
 
’나머지 구하기'를 제쳐두고 a의 b승을 하면, 숫자가 너무 커져서 long long 으로 연산이 불가능하다. 
 
따라서 ‘a를 c로 나눈 나머지'만 기억하면서 연산해야 한다. 
예를 들어, a의 1승은 a % c 가 되어야 한다. 
a의 2승은 (a % c) * (a % c) 가 되어야 한다. 
 
2의 4승 == ( 2의 2승 * 2의 2승 ) 임을 이용해서 분할정복으로 구현했다. 
 
짝수 b승을 계산할 때, 
b/2 승 * b/2 승을 연산하되, 마지막에는 반드시 c로 나눈 나머지를 저장하자. 
 

 

728x90

'알고리즘 > 백준' 카테고리의 다른 글

Hasing 백준 15829번 c++  (0) 2022.02.11
시리얼 번호 백준 1431번 c++  (0) 2022.02.10
큰 수 A+B 백준 10757번 c++  (0) 2022.02.09
피보나치 수 4 백준 10826번 c++  (0) 2022.02.08
피보나치 수 5 백준 10870번 c++  (0) 2022.02.08

+ Recent posts