haar_lib/math/
tetration.rs

1//! $a \uparrow \uparrow b \pmod m$
2//!
3//! # Problems
4//! - <https://judge.yosupo.jp/problem/tetration_mod>
5use crate::math::{mod_ops::pow::mod_pow, totient::totient};
6
7/// $a \uparrow \uparrow b \pmod m$を求める。
8pub fn tetration(a: u64, b: u64, m: u64) -> u64 {
9    rec(a, b, m) % m
10}
11
12fn rec(a: u64, b: u64, m: u64) -> u64 {
13    match b {
14        0 => 1 % m,
15        1 => a % m,
16        2 => mod_pow(a, a, m),
17        _ if a == 0 => 1 - b % 2,
18        _ if m == 1 => 1,
19        _ => {
20            let phi = totient(m);
21            let mut p = rec(a, b - 1, phi);
22
23            if p == 0 {
24                p = phi;
25            }
26
27            mod_pow(a, p, m)
28        }
29    }
30}