티스토리 뷰

728x90

문제 링크

www.acmicpc.net/problem/1629

 

1629번: 곱셈

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

www.acmicpc.net

 

풀이

$a^b$를 $c$로 나눈 나머지를 출력해야 합니다.

거듭제곱을 단순하게 구현하면 $\text{O}(b)$의 시간 복잡도가 나오므로 적절히 최적화를 해줘야 합니다.

 

1) 만약 $b$가 홀수라면, $a^b = a\cdot a^{b-1}$ 입니다.

2) 만약 $b$가 짝수라면, $a^b = a^{b/2}\cdot a^{b/2}$ 입니다.

 

이런 식으로 짝수일 때 $b$의 범위를 반씩 줄여나가면 $\text{O}(\log b)$의 복잡도로 거듭제곱을 구현할 수 있습니다.

 

구현 시 주의사항이 있습니다. 재귀 함수로 구현할 때 $f(a, b/2)*f(a, b/2)$와 같이 함수를 호출하면 복잡도가 줄어들지 않습니다.

$f(a, b/2)$의 결과를 따로 저장해둔 뒤 그 값의 곱을 반환하도록 합시다.

 

정답 코드

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

ll a, b, m;

ll go(ll n, ll k) {
    if (k == 1) return n;
    if (k & 1) return n * go(n, k - 1) % m;
    ll res = go(n, k / 2);
    return res * res % m;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> a >> b >> m;
    cout << go(a % m, b);
}
728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함