結果
| 問題 | No.181 A↑↑N mod M |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-12-02 16:50:56 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 5,000 ms |
| コード長 | 3,468 bytes |
| コンパイル時間 | 2,418 ms |
| コンパイル使用メモリ | 206,920 KB |
| 最終ジャッジ日時 | 2025-02-09 03:13:09 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 6 |
| other | AC * 37 |
ソースコード
#include <bits/stdc++.h>
unsigned long long modmul(unsigned long long a, unsigned long long b,
unsigned long long M) {
long long ret =
a * b - M * static_cast<unsigned long long>(1.L / M * a * b);
return ret + M * (ret < 0) - M * (ret >= static_cast<long long>(M));
}
unsigned long long modpow(unsigned long long b, unsigned long long e,
unsigned long long mod) {
unsigned long long ans = 1;
for (; e; b = modmul(b, b, mod), e /= 2) {
if (e & 1) {
ans = modmul(ans, b, mod);
}
}
return ans;
}
bool is_prime(unsigned long long n) {
if (n < 2 || n % 6 % 4 != 1) {
return (n | 1) == 3;
}
unsigned long long A[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022},
s = __builtin_ctzll(n - 1), d = n >> s;
for (unsigned long long a : A) {
unsigned long long p = modpow(a % n, d, n), i = s;
while (p != 1 && p != n - 1 && a % n && i--) {
p = modmul(p, p, n);
}
if (p != n - 1 && i != s) {
return 0;
}
}
return 1;
}
unsigned long long pollard(unsigned long long n) {
auto f = [n](unsigned long long x) { return modmul(x, x, n) + 1; };
unsigned long long x = 0, y = 0, t = 30, prd = 2, i = 1, q;
while (t++ % 40 || std::gcd(prd, n) == 1) {
if (x == y) {
x = ++i, y = f(x);
}
if ((q = modmul(prd, std::max(x, y) - std::min(x, y), n))) {
prd = q;
}
x = f(x), y = f(f(y));
}
return std::gcd(prd, n);
}
std::vector<unsigned long long> factor(unsigned long long n) {
if (n == 1) {
return {};
}
if (is_prime(n)) {
return {n};
}
unsigned long long x = pollard(n);
auto l = factor(x), r = factor(n / x);
l.insert(l.end(), r.begin(), r.end());
return l;
}
unsigned long long euler_phi(unsigned long long n) {
auto f = factor(n);
std::sort(f.begin(), f.end());
f.erase(std::unique(f.begin(), f.end()), f.end());
for (auto p : f) {
n -= n / p;
}
return n;
}
template <typename T, typename Promote = unsigned long long>
T power_tower(const std::vector<T> &a, T m) {
static_assert(std::is_integral_v<T>);
assert(m > 0);
std::vector<unsigned long long> mod_chain{
static_cast<unsigned long long>(m)};
while (mod_chain.back() > 1) {
const auto phi = euler_phi(mod_chain.back());
mod_chain.push_back(phi);
}
const auto f = [](Promote x, Promote n, Promote mod) {
Promote r = 1;
if (x > mod) {
x = x % mod + mod;
}
while (n) {
if (n & 1) {
r *= x;
if (r > mod) {
r = r % mod + mod;
}
}
x *= x;
if (x > mod) {
x = x % mod + mod;
}
n >>= 1;
}
return r;
};
Promote r = 1;
const auto k = static_cast<int>(std::min(a.size(), mod_chain.size()));
for (auto i = k - 1; i >= 0; --i) {
assert(a[i] > 0);
r = f(static_cast<Promote>(a[i]), r, mod_chain[i]);
}
return static_cast<T>(r % static_cast<Promote>(m));
}
int main() {
std::cin.tie(0)->sync_with_stdio(0);
int A, N, M;
std::cin >> A >> N >> M;
std::vector<int> a(std::min(N, 24), A);
std::cout << power_tower(a, M);
}