출처: https://3months.tistory.com/307 [Deep Play]

백준/Math

[BOJ] 1629 곱셈

코딩하는 랄뚜기 2022. 3. 20. 19:53

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

 

1629번: 곱셈

첫째 줄에 A, B, C가 빈 칸을 사이에 두고 순서대로 주어진다. A, B, C는 모두 2,147,483,647 이하의 자연수이다.

www.acmicpc.net


문제

자연수 A를 B번 곱한 수를 알고 싶다. 단 구하려는 수가 매우 커질 수 있으므로 이를 C로 나눈 나머지를 구하는 프로그램을 작성하시오.


입력

첫째 줄에 A, B, C가 빈 칸을 사이에 두고 순서대로 주어진다. A, B, C는 모두 2,147,483,647 이하의 자연수이다.


출력

첫째 줄에 A를 B번 곱한 수를 C로 나눈 나머지를 출력한다.


풀이

B 만큼 반복문을 돌면 B의 최대 크기가 2,147,483,647이므로 시간초과가 발생한다.

 A^(B/2)를 계산했다면 또 다시 A^(B/2)를 계산 할 필요가 없다.

따라서 분할정복을 이용하여 문제를 해결하면 된다.


코드

#include <string>
#include <stdio.h>
#include <math.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#include <climits>
#include <set>

#define p(a, b) make_pair(a, b)
#define SWAP(a, b, type) do { \
    type temp; \
    temp = a;  \
    a = b;     \
    b = temp;  \
} while (0)
#define INF 1000000000
#define endl '\n'
#define ll long long

using namespace std;

ll a,b,c;

ll cnt=0;

ll cal(ll a,ll b){
    cnt++;
    if(b==0) return 1;
    if(b==1) return a;
    if(b%2!=0) return (cal(a,b-1)*a)%c;
    
    ll h=cal(a,b/2)%c; // 분할 정복을 통해
    return (h*h)%c;
}

void input() {
    cin>>a>>b>>c;
}

void init() {
}


void solution() {
    cout<<cal(a,b)%c;
}

int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    input();
    solution();
    return 0;
}

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

[BOJ] 9375 패션왕 신해빈  (0) 2022.03.18
[BOJ] 2609 최대공약수와 최소공배수  (0) 2022.03.07
[BOJ] 20943 카카오톡  (0) 2022.02.20