https://www.acmicpc.net/problem/12445
12445번: バクテリアの増殖 (Small)
微生物の研究者であるパスカルは、特殊な増殖の傾向を示すバクテリアを発見した。どうやらそのバクテリアは、ある時点で x 個存在したとすると、理想的な環境下では1時間後に xx 個に増
www.acmicpc.net
번역기를 돌려보면 대충 문제가 말하는 것을 파악할 수 있습니다.
초기의 박테리아의 수는 문제에서 주어지는 인풋인 $A$ 이니까, 수열 $\left \{ X_{N} \right \}$ 을 이렇게 정의합시다.
$X_{0}=A$
$X_{k}=\left ( X_{k-1} \right )^{X_{k-1}}$ (단, $1\leq k$ )
우리는 $B$ 를 인풋받아 $X_{B}$ mod $C$ 를 구해야 합니다.
이 문제는 Small 버전이라서, $1\leq B\leq 2$ 입니다.
따라서, 각각의 케이스에 대해 구현할 수 있습니다.
$B=1$ 일 때는, 단순히 $A^{A}$ mod $C$ 를 구하면 됩니다.
$B=2$ 일 때는, euler's theorem을 활용합니다.
즉, 다음과 같습니다.
$\left ( A^{A} \right )^{ \left ( A^{A} \right ) }\;\; mod\;\; C = \left ( A^{A}\;\; mod\;\; C \right )^{\left ( A^{A}\;\; mod\;\; \phi \left ( C \right )\right )}\;\; mod\;\; C$
단, 지수 부분이 0이 되지 않도록 예외처리를 조금 해주어야 합니다.
최종적인 코드는 다음과 같습니다.
#include <stdio.h>
int phi (int X);
int power_modular (int X, int Y, int mod);
int main() {
int T;
scanf("%d", &T);
for (int i = 1; i <= T; i++) {
int A, B, C;
scanf("%d %d %d", &A, &B, &C);
int Answer;
if (B == 1) {
Answer = power_modular (A, A, C);
}
else {
int Base = power_modular (A, A, C);
if (Base == 0) {
Answer = 0;
}
else {
int Power = power_modular (A, A, phi(C));
if (Power == 0) {
Power += phi(C);
}
Answer = power_modular (Base, Power, C);
}
}
printf("Case #%d: %d\n", i, Answer);
}
return 0;
}
int phi (int X) {
int answer = X;
for (int j = 2; j * j <= X; j++) {
if (X % j == 0) {
while (X % j == 0) {
X /= j;
}
answer -= answer / j;
}
}
if (X > 1) {
answer -= answer / X;
}
return answer;
}
int power_modular (int X, int Y, int mod) {
int answer = 1;
while(Y) {
if (Y % 2) {
answer = (answer * X) % mod;
}
X = (X * X) % mod;
Y /= 2;
}
return answer;
}
(C11, 1116KB, 0ms, 제출번호 27527547)
'분할 정복을 이용한 거듭제곱 > 정수 거듭제곱' 카테고리의 다른 글
백준 13173번: Ω (0) | 2021.07.31 |
---|---|
백준 12446번: バクテリアの増殖 (Large) (0) | 2021.07.19 |
백준 11693번: n^m 의 약수의 합 (0) | 2021.07.18 |
백준 21854번: Monsters (0) | 2021.07.18 |
백준 2709번: 가장 작은 K (0) | 2021.03.28 |