P4139 上帝与集合的正确用法
根据题意 求 \(2^{2^{2^ {. ^{. ^{. ^{2}}}}}} \bmod p\), 题目已说明必然存在 \(a_n \bmod p\) 之后都是同一个值。
根据欧拉降幂公式:
\[A^k \equiv A^{k \% \phi(p) + \phi(p)} (\bmod p)
\]
所以我们可以考虑对指数取模。
其实根据\(\phi(p) \space p \ge2\) 都为偶数,由欧拉函数公式知偶数\(p\), 一定满足不等式 \(\phi(p) \le \frac{p}{2}\), 不断的递归\(\phi(p) \rightarrow \phi(\phi(p)) \rightarrow \dots\) 其实是一个不断减小的过程,所以必然存在结束条件 \(\phi(x) = 1\), 即指数取模后为 \(0\)(若不为 \(1\) 则我们需要不断的进行递归)。
Code
#include <bits/stdc++.h>
using i64 = long long;
int phi(int x) {
int res = x;
for (int i = 2; i <= x / i; i ++) {
if (x % i == 0) {
res = res / i * (i - 1);
while (x % i == 0) x /= i;
}
}
if (x > 1) res = res / x * (x - 1);
return res;
}
i64 fast_pow(i64 a, i64 b, i64 mod) {
i64 res = 1;
while (b) {
if (b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
i64 solve(i64 x) {
if (x == 1) return 0;
int pp = phi(x);
return fast_pow(2ll, solve(pp) + pp, x);
}
int main() {
int _; std::cin >> _;
while (_ --) {
int p; std::cin >> p;
std::cout << solve(p) << "\n";
}
}
P4139 上帝与集合的正确用法